转载

基类+自定义导航条(iOS 11 & iPhone X适配)

曾经写过一个基类控制器, 封装了一个自定义的NavigationBar, 如今原工程直接跑在iOS 11上的效果:

基类+自定义导航条(iOS 11 & iPhone X适配)

iOS 11默认.png

感觉整体向上移动了20个点, 正好是状态栏的高度, 不过仔细看层级结构对照可以发现, 导航栏的高度还是64, 内部的子视图向上移动了导航栏高度的距离.

在自定义的UINavigationBar中,遍历找到需要的控件,对size.height和origin.y和响应调整,注意版本适配, iOS10之前使用的是_UINavigationBarBackground, iOS10起改为_UIBarBackground

iOS 10:
 
   | <_UIBarBackground: 0x101824e60; frame = (0 0; 375 44); userInteractionEnabled = NO; layer = >
   |    | 
   |    | 
   |    |    | <_UIVisualEffectBackdropView: 0x1018564f0; frame = (0 0; 0 0); autoresize = W+H; userInteractionEnabled = NO; layer = >
   |    |    | <_UIVisualEffectSubview: 0x10185a730; frame = (0 0; 0 0); autoresize = W+H; userInteractionEnabled = NO; layer = >
   |    |    | <_UIVisualEffectSubview: 0x10185a930; frame = (0 0; 0 0); alpha = 0.85; autoresize = W+H; userInteractionEnabled = NO; layer = >
   | <_UINavigationBarLargeTitleView: 0x100732f70; frame = (0 0; 375 64); clipsToBounds = YES; hidden = YES; layer = >
   |    | 
   | <_UINavigationBarContentView: 0x101831fd0; frame = (0 0; 375 44); layer = >
   |    | <_UIButtonBarStackView: 0x101810f90; frame = (0 0; 0 0); layer = >
   |    |    | <_UITAMICAdaptorView: 0x10185c430; frame = (0 0; 33 32); autoresizesSubviews = NO; layer = >
   |    |    |    | 
   |    |    |    |    | 
   |    | 
   | <_UINavigationBarModernPromptView: 0x100733920; frame = (0 0; 375 64); alpha = 0; hidden = YES; layer = >
   |    | 
Eailier:
 
   | <_UINavigationBarBackground: 0x7f9657cae8d0; frame = (0 0; 414 64); opaque = NO; userInteractionEnabled = NO; layer = >
   |    | <_UIBackdropView: 0x7f9657f3d4b0; frame = (0 0; 414 64); opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = >
   |    |    | <_UIBackdropEffectView: 0x7f9657e0c090; frame = (0 0; 414 64); clipsToBounds = YES; opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = >
   |    |    | 
   |    |    | 
   |    | 
   | 
   |    | 
   |    |    |  (layer)
   | 
   |    | 
   |    |    |  (layer)
   | <_UINavigationBarBackIndicatorView: 0x7f9657f3f270; frame = (12 31.6667; 13 21); alpha = 0; opaque = NO; userInteractionEnabled = NO; layer = >

适配代码:

- (void)layoutSubviews
{
    [super layoutSubviews];
    CGFloat systemVersion = [UIDevice currentDevice].systemVersion.floatValue;
    for (UIView *view in self.subviews) {
        if (systemVersion >= 11.0) {
            if ([view isKindOfClass:NSClassFromString(@"_UIBarBackground")]) {
                NSLog(@"_UIBarBackground");
                CGRect frame = view.frame;
                frame.size.height = 64;
                if (IS_IPHONE_X) {
                    frame.origin.y = 24;
                }
                view.frame = frame;
                NSLog(@"修改后的Frame: %@",NSStringFromCGRect(view.frame));
            }
            if ([view isKindOfClass:NSClassFromString(@"_UINavigationBarContentView")]) {
                NSLog(@"_UINavigationBarContentView");
                CGRect frame = view.frame;
                frame.origin.y = 20;
                if (IS_IPHONE_X) {
                    frame.origin.y = 44;
                }
                view.frame = frame;
            }
        }
    }
}

这样iOS 11下就恢复正常了

正文到此结束
Loading...