From cadd93b10330ff57b14b8bc0c1e0a6d8af1ca64d Mon Sep 17 00:00:00 2001 From: QuintGao <1094887059@qq.com> Date: Wed, 26 Jan 2022 16:29:11 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=82=E9=85=8D=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- GKNavigationBar.podspec | 2 +- .../NavigationBar/GKNavigationBarConfigure.h | 6 +- .../NavigationBar/GKNavigationBarConfigure.m | 212 ++++++++++++++---- README.md | 1 + 4 files changed, 172 insertions(+), 49 deletions(-) diff --git a/GKNavigationBar.podspec b/GKNavigationBar.podspec index c6c9b64..e928271 100644 --- a/GKNavigationBar.podspec +++ b/GKNavigationBar.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'GKNavigationBar' - s.version = '1.6.5' + s.version = '1.6.6' s.license = 'MIT' s.summary = '自定义导航栏--导航栏联动' s.homepage = 'https://github.com/QuintGao/GKNavigationBar' diff --git a/GKNavigationBar/NavigationBar/GKNavigationBarConfigure.h b/GKNavigationBar/NavigationBar/GKNavigationBarConfigure.h index 963e5dd..82ff39a 100644 --- a/GKNavigationBar/NavigationBar/GKNavigationBarConfigure.h +++ b/GKNavigationBar/NavigationBar/GKNavigationBarConfigure.h @@ -133,7 +133,7 @@ NS_ASSUME_NONNULL_BEGIN @property (class, nonatomic, readonly) BOOL is65InchScreen; /// iPhone 12 / 12 Pro -@property (class, nonatomic, readonly) BOOL is61InchScreenAndiPhone12; +@property (class, nonatomic, readonly) BOOL is61InchScreenAndiPhone12Later; /// iPhone XR / 11 @property (class, nonatomic, readonly) BOOL is61InchScreen; @@ -158,7 +158,7 @@ NS_ASSUME_NONNULL_BEGIN @property (class, nonatomic, readonly) CGSize screenSizeFor67Inch; @property (class, nonatomic, readonly) CGSize screenSizeFor65Inch; -@property (class, nonatomic, readonly) CGSize screenSizeFor61InchAndiPhone12; +@property (class, nonatomic, readonly) CGSize screenSizeFor61InchAndiPhone12Later; @property (class, nonatomic, readonly) CGSize screenSizeFor61Inch; @property (class, nonatomic, readonly) CGSize screenSizeFor58Inch; @property (class, nonatomic, readonly) CGSize screenSizeFor55Inch; @@ -186,7 +186,7 @@ NS_ASSUME_NONNULL_BEGIN @property (class, nonatomic, readonly) CGRect statusBarFrame; @property (class, nonatomic, readonly) UIWindow *keyWindow; -// 用于获取 isNotchedScreen 设备的 insets,注意对于 iPad Pro 11-inch 这种无刘海凹槽但却有使用 Home Indicator 的设备,它的 top 返回0,bottom 返回 safeAreaInsets.bottom 的值 +/// 用于获取 isNotchedScreen 设备的 insets,注意对于无 Home 键的新款 iPad 而言,它不一定有物理凹槽,但因为使用了 Home Indicator,所以它的 safeAreaInsets 也是非0。 + (UIEdgeInsets)safeAreaInsetsForDeviceWithNotch; @end diff --git a/GKNavigationBar/NavigationBar/GKNavigationBarConfigure.m b/GKNavigationBar/NavigationBar/GKNavigationBarConfigure.m index aab29d9..a62b539 100644 --- a/GKNavigationBar/NavigationBar/GKNavigationBarConfigure.m +++ b/GKNavigationBar/NavigationBar/GKNavigationBarConfigure.m @@ -76,7 +76,7 @@ - (UIViewController *)visibleViewController { - (CGFloat)gk_fixedSpace { // 经测试发现iPhone 12和iPhone 12 Pro,默认导航栏间距是16,需要单独处理 - if ([GKNavigationBarConfigure is61InchScreenAndiPhone12]) return 16; + if ([GKNavigationBarConfigure is61InchScreenAndiPhone12Later]) return 16; return GK_DEVICE_WIDTH > 375.0f ? 20 : 16; } @@ -89,6 +89,21 @@ - (NSBundle *)gk_libraryBundle { @end +@interface GKPortraitViewController : UIViewController +@end + +@implementation GKPortraitViewController + +- (BOOL)shouldAutorotate { + return NO; +} + +- (UIInterfaceOrientationMask)supportedInterfaceOrientations { + return UIInterfaceOrientationMaskPortrait; +} + +@end + @implementation GKNavigationBarConfigure (UIDevice) + (NSString *)deviceModel { @@ -173,38 +188,35 @@ + (BOOL)isMac { static NSInteger isNotchedScreen = -1; + (BOOL)isNotchedScreen { - if (@available(iOS 11, *)) { - if (isNotchedScreen < 0) { - if (@available(iOS 12.0, *)) { - /* - 检测方式解释/测试要点: - 1. iOS 11 与 iOS 12 可能行为不同,所以要分别测试。 - 2. 与触发 [QMUIHelper isNotchedScreen] 方法时的进程有关,例如 https://github.com/Tencent/QMUI_iOS/issues/482#issuecomment-456051738 里提到的 [NSObject performSelectorOnMainThread:withObject:waitUntilDone:NO] 就会导致较多的异常。 - 3. iOS 12 下,在非第2点里提到的情况下,iPhone、iPad 均可通过 UIScreen -_peripheryInsets 方法的返回值区分,但如果满足了第2点,则 iPad 无法使用这个方法,这种情况下要依赖第4点。 - 4. iOS 12 下,不管是否满足第2点,不管是什么设备类型,均可以通过一个满屏的 UIWindow 的 rootViewController.view.frame.origin.y 的值来区分,如果是非全面屏,这个值必定为20,如果是全面屏,则可能是24或44等不同的值。但由于创建 UIWindow、UIViewController 等均属于较大消耗,所以只在前面的步骤无法区分的情况下才会使用第4点。 - 5. 对于第4点,经测试与当前设备的方向、是否有勾选 project 里的 General - Hide status bar、当前是否处于来电模式的状态栏这些都没关系。 - */ - SEL peripheryInsetsSelector = NSSelectorFromString([NSString stringWithFormat:@"_%@%@", @"periphery", @"Insets"]); - UIEdgeInsets peripheryInsets = UIEdgeInsetsZero; - [self object:[UIScreen mainScreen] performSelector:peripheryInsetsSelector returnValue:&peripheryInsets]; + if (isNotchedScreen < 0) { + if (@available(iOS 12.0, *)) { + /* + 检测方式解释/测试要点: + 1. iOS 11 与 iOS 12 可能行为不同,所以要分别测试。 + 2. 与触发 [QMUIHelper isNotchedScreen] 方法时的进程有关,例如 https://github.com/Tencent/QMUI_iOS/issues/482#issuecomment-456051738 里提到的 [NSObject performSelectorOnMainThread:withObject:waitUntilDone:NO] 就会导致较多的异常。 + 3. iOS 12 下,在非第2点里提到的情况下,iPhone、iPad 均可通过 UIScreen -_peripheryInsets 方法的返回值区分,但如果满足了第2点,则 iPad 无法使用这个方法,这种情况下要依赖第4点。 + 4. iOS 12 下,不管是否满足第2点,不管是什么设备类型,均可以通过一个满屏的 UIWindow 的 rootViewController.view.frame.origin.y 的值来区分,如果是非全面屏,这个值必定为20,如果是全面屏,则可能是24或44等不同的值。但由于创建 UIWindow、UIViewController 等均属于较大消耗,所以只在前面的步骤无法区分的情况下才会使用第4点。 + 5. 对于第4点,经测试与当前设备的方向、是否有勾选 project 里的 General - Hide status bar、当前是否处于来电模式的状态栏这些都没关系。 + */ + SEL peripheryInsetsSelector = NSSelectorFromString([NSString stringWithFormat:@"_%@%@", @"periphery", @"Insets"]); + UIEdgeInsets peripheryInsets = UIEdgeInsetsZero; + [self object:[UIScreen mainScreen] performSelector:peripheryInsetsSelector returnValue:&peripheryInsets]; + if (peripheryInsets.bottom <= 0) { + UIWindow *window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds]; + peripheryInsets = window.safeAreaInsets; if (peripheryInsets.bottom <= 0) { - UIWindow *window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds]; - peripheryInsets = window.safeAreaInsets; - if (peripheryInsets.bottom <= 0) { - UIViewController *viewController = [UIViewController new]; - window.rootViewController = viewController; - if (CGRectGetMinY(viewController.view.frame) > 20) { - peripheryInsets.bottom = 1; - } + // 使用一个强制竖屏的rootViewController,避免一个仅支持竖屏的App在横屏启动时会受到这里创建的window的影响,导致状态栏、safeAreaInsets等错乱 + GKPortraitViewController *viewController = [GKPortraitViewController new]; + window.rootViewController = viewController; + if (CGRectGetMinY(viewController.view.frame) > 20) { + peripheryInsets.bottom = 1; } } - isNotchedScreen = peripheryInsets.bottom > 0 ? 1 : 0; - } else { - isNotchedScreen = [self is58InchScreen] ? 1 : 0; } + isNotchedScreen = peripheryInsets.bottom > 0 ? 1 : 0; + } else { + isNotchedScreen = [self is58InchScreen] ? 1 : 0; } - } else { - isNotchedScreen = 0; } return isNotchedScreen > 0; } @@ -241,12 +253,12 @@ + (BOOL)is65InchScreen { return is65InchScreen > 0; } -static NSInteger is61InchScreenAndiPhone12 = -1; -+ (BOOL)is61InchScreenAndiPhone12 { - if (is61InchScreenAndiPhone12 < 0) { - is61InchScreenAndiPhone12 = (GK_DEVICE_WIDTH == self.screenSizeFor61InchAndiPhone12.width && GK_DEVICE_HEIGHT == self.screenSizeFor61InchAndiPhone12.height && ([[self deviceModel] isEqualToString:@"iPhone13,2"] || [[self deviceModel] isEqualToString:@"iPhone13,3"])) ? 1 : 0; +static NSInteger is61InchScreenAndiPhone12Later = -1; ++ (BOOL)is61InchScreenAndiPhone12Later { + if (is61InchScreenAndiPhone12Later < 0) { + is61InchScreenAndiPhone12Later = (GK_DEVICE_WIDTH == self.screenSizeFor61InchAndiPhone12Later.width && GK_DEVICE_HEIGHT == self.screenSizeFor61InchAndiPhone12Later.height) ? 1 : 0; } - return is61InchScreenAndiPhone12 > 0; + return is61InchScreenAndiPhone12Later > 0; } static NSInteger is61InchScreen = -1; @@ -318,7 +330,7 @@ + (CGSize)screenSizeFor65Inch { return CGSizeMake(414, 896); } -+ (CGSize)screenSizeFor61InchAndiPhone12 { ++ (CGSize)screenSizeFor61InchAndiPhone12Later { return CGSizeMake(390, 844); } @@ -466,26 +478,136 @@ + (UIEdgeInsets)safeAreaInsetsForDeviceWithNotch { } if ([self isIPad]) { - return UIEdgeInsetsMake(0, 0, 20, 0); + return UIEdgeInsetsMake(24, 0, 20, 0); } + static NSDictionary *> *dict; + if (!dict) { + dict = @{ + // iPhone 13 mini + @"iPhone14,4": @{ + @(UIInterfaceOrientationPortrait): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(50, 0, 34, 0)], + @(UIInterfaceOrientationLandscapeLeft): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(0, 50, 21, 50)], + }, + @"iPhone14,4-Zoom": @{ + @(UIInterfaceOrientationPortrait): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(43, 0, 29, 0)], + @(UIInterfaceOrientationLandscapeLeft): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(0, 43, 21, 43)], + }, + // iPhone 13 + @"iPhone14,5": @{ + @(UIInterfaceOrientationPortrait): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(47, 0, 34, 0)], + @(UIInterfaceOrientationLandscapeLeft): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(0, 47, 21, 47)], + }, + @"iPhone14,5-Zoom": @{ + @(UIInterfaceOrientationPortrait): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(39, 0, 28, 0)], + @(UIInterfaceOrientationLandscapeLeft): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(0, 39, 21, 39)], + }, + // iPhone 13 Pro + @"iPhone14,2": @{ + @(UIInterfaceOrientationPortrait): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(47, 0, 34, 0)], + @(UIInterfaceOrientationLandscapeLeft): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(0, 47, 21, 47)], + }, + @"iPhone14,2-Zoom": @{ + @(UIInterfaceOrientationPortrait): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(39, 0, 28, 0)], + @(UIInterfaceOrientationLandscapeLeft): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(0, 39, 21, 39)], + }, + // iPhone 13 Pro Max + @"iPhone14,3": @{ + @(UIInterfaceOrientationPortrait): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(47, 0, 34, 0)], + @(UIInterfaceOrientationLandscapeLeft): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(0, 47, 21, 47)], + }, + @"iPhone14,3-Zoom": @{ + @(UIInterfaceOrientationPortrait): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(41, 0, 29 + 2.0 / 3.0, 0)], + @(UIInterfaceOrientationLandscapeLeft): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(0, 41, 21, 41)], + }, + + + // iPhone 12 mini + @"iPhone13,1": @{ + @(UIInterfaceOrientationPortrait): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(50, 0, 34, 0)], + @(UIInterfaceOrientationLandscapeLeft): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(0, 50, 21, 50)], + }, + @"iPhone13,1-Zoom": @{ + @(UIInterfaceOrientationPortrait): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(43, 0, 29, 0)], + @(UIInterfaceOrientationLandscapeLeft): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(0, 43, 21, 43)], + }, + // iPhone 12 + @"iPhone13,2": @{ + @(UIInterfaceOrientationPortrait): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(47, 0, 34, 0)], + @(UIInterfaceOrientationLandscapeLeft): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(0, 47, 21, 47)], + }, + @"iPhone13,2-Zoom": @{ + @(UIInterfaceOrientationPortrait): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(39, 0, 28, 0)], + @(UIInterfaceOrientationLandscapeLeft): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(0, 39, 21, 39)], + }, + // iPhone 12 Pro + @"iPhone13,3": @{ + @(UIInterfaceOrientationPortrait): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(47, 0, 34, 0)], + @(UIInterfaceOrientationLandscapeLeft): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(0, 47, 21, 47)], + }, + @"iPhone13,3-Zoom": @{ + @(UIInterfaceOrientationPortrait): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(39, 0, 28, 0)], + @(UIInterfaceOrientationLandscapeLeft): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(0, 39, 21, 39)], + }, + // iPhone 12 Pro Max + @"iPhone13,4": @{ + @(UIInterfaceOrientationPortrait): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(47, 0, 34, 0)], + @(UIInterfaceOrientationLandscapeLeft): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(0, 47, 21, 47)], + }, + @"iPhone13,4-Zoom": @{ + @(UIInterfaceOrientationPortrait): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(41, 0, 29 + 2.0 / 3.0, 0)], + @(UIInterfaceOrientationLandscapeLeft): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(0, 41, 21, 41)], + }, + + + // iPhone 11 + @"iPhone12,1": @{ + @(UIInterfaceOrientationPortrait): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(48, 0, 34, 0)], + @(UIInterfaceOrientationLandscapeLeft): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(0, 48, 21, 48)], + }, + @"iPhone12,1-Zoom": @{ + @(UIInterfaceOrientationPortrait): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(44, 0, 31, 0)], + @(UIInterfaceOrientationLandscapeLeft): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(0, 44, 21, 44)], + }, + // iPhone 11 Pro Max + @"iPhone12,5": @{ + @(UIInterfaceOrientationPortrait): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(44, 0, 34, 0)], + @(UIInterfaceOrientationLandscapeLeft): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(0, 44, 21, 44)], + }, + @"iPhone12,5-Zoom": @{ + @(UIInterfaceOrientationPortrait): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(40, 0, 30 + 2.0 / 3.0, 0)], + @(UIInterfaceOrientationLandscapeLeft): [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(0, 40, 21, 40)], + }, + }; + } + + NSString *deviceKey = [self deviceModel]; + if (!dict[deviceKey]) { + deviceKey = @"iPhone14,2"; // 默认按最新的 iPhone 13 Pro 处理,因为新出的设备肯定更大概率与上一代设备相似 + } + if ([self isZoomedMode]) { + deviceKey = [NSString stringWithFormat:@"%@-Zoom", deviceKey]; + } + + NSNumber *orientationKey = nil; UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; switch (orientation) { - case UIInterfaceOrientationPortrait: - return UIEdgeInsetsMake(44, 0, 34, 0); - - case UIInterfaceOrientationPortraitUpsideDown: - return UIEdgeInsetsMake(34, 0, 44, 0); - case UIInterfaceOrientationLandscapeLeft: case UIInterfaceOrientationLandscapeRight: - return UIEdgeInsetsMake(0, 44, 21, 44); - - case UIInterfaceOrientationUnknown: + orientationKey = @(UIInterfaceOrientationLandscapeLeft); + break; default: - return UIEdgeInsetsMake(44, 0, 34, 0); + orientationKey = @(UIInterfaceOrientationPortrait); + break; + } + UIEdgeInsets insets = dict[deviceKey][orientationKey].UIEdgeInsetsValue; + if (orientation == UIInterfaceOrientationPortraitUpsideDown) { + insets = UIEdgeInsetsMake(insets.bottom, insets.left, insets.top, insets.right); + }else if (orientation == UIInterfaceOrientationLandscapeRight) { + insets = UIEdgeInsetsMake(insets.top, insets.right, insets.bottom, insets.left); } + return insets; } @end diff --git a/README.md b/README.md index 49e4668..f68df02 100644 --- a/README.md +++ b/README.md @@ -206,6 +206,7 @@ configure.shiledGuestureVCs = @[NSClassFromString(@"TZPhotoPickerController"), @ 最近更新 ``` +1.6.6 - 2022.01.26 新机型适配优化 1.6.5 - 2022.01.20 修复设置gk_disableFixNavItemSpace后gk_disableFixSpace无效的bug#93 1.6.4 - 2022.01.04 新增darkBackgroundImage、darkLineImage等适配暗黑模式导航图片 1.6.2 - 2021.12.29 修复设置gk_disableFixSpace为YES无效的bug #16