美文网首页
[iOS10]Xcode8系统导航适配

[iOS10]Xcode8系统导航适配

作者: 流火绯瞳 | 来源:发表于2016-09-29 11:46 被阅读1084次

    开发环境

    Xcode 8
    iOS 10

    Xcode 7.3
    iOS9.3

    问题

    最近有个朋友问我,在适配iOS10的时候,导航的图片不显示了,使用的是系统导航,怎么调整都不显示.
    在Xcode7.3,iOS9.3显示如下:

    Xcode7.3-iOS9.3正常情况下

    导航中间位置有一个LOGO视图(当然不是这个条形码),而在Xcode8-iOS10上,这个视图不显示了,如下:

    iOS10视图不见了

    我看了他添加视图的代码,如下:

    -(void)setNavigationBarBackgroundView:(UIView *)backgroundView
    {
        NSArray * subs  =[self.navigationBar subviews];
        UIView  * bgview=nil;
        
        for (UIView  * v in subs)
        {
            NSString * classname = NSStringFromClass([v class]);
            if ([classname isEqualToString:@"_UINavigationBarBackground"] || [classname isEqualToString:@"UINavigationBarBackground"])
            {
                bgview=v;
                break;
            }
        }
    
        if (bgview!=nil)
        {
            int systemVersion =[[UIDevice currentDevice].systemVersion intValue];
            UIView * container=[bgview viewWithTag:20001];
            if (!container)
            {
                CGRect r;
                if (systemVersion>=7)
                {
                    r=CGRectMake(0, 0, bgview.frame.size.width, 64);
                }else{
                    r=CGRectMake(0, 0, bgview.frame.size.width, 44);
                }
                container = [[UIView alloc] initWithFrame:r];
                [container setBackgroundColor:[UIColor whiteColor]];
                [container setTag:20001];
                [bgview addSubview:container];
                [container release];
            }
            
            [bgview setUserInteractionEnabled:YES];
            
            UIView * v=[container viewWithTag:20000];
            if ([v isEqual:backgroundView])
            {
                return;
            }
            if (v)
            {
                [v removeFromSuperview];
            }
            float h=container.frame.size.height;
            if (![backgroundView isKindOfClass:[UIImageView class]])
            {
                h=44;
            }
            CGRect rect=backgroundView.frame;
            rect.origin.x=0;
            rect.origin.y=container.frame.size.height-h;
            rect.size.width=bgview.frame.size.width;
            rect.size.height=h;
            [backgroundView setFrame:rect];
            [backgroundView setTag:20000];
            [container addSubview:backgroundView];
        }
    }
    

    是不是看到了个不和谐的词** release** ,好吧,这是个最低要适配到6.0的古董级的项目了....

    排查问题

    当时看了他的导航视图,我的第一反应是,为什么不自定义个呢?岂不是要省事很多?好吧,系统的有问题,也是需要解决的,原谅我自定义的导航用多了...
    我第一个想到的是,这个bgView是不是存在的,所以打个断点后发现,这个bgView是nil,所以我重新打印了导航视图的子视图:

    (
        "<_UIBarBackground: 0x7f86cdd0b4e0; frame = (0 0; 320 44); userInteractionEnabled = NO; layer = <CALayer: 0x6000000273c0>>",
        "<_UINavigationBarBackIndicatorView: 0x7f86cdc0d6c0; frame = (0 11.5; 13 21); alpha = 0; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x60800002a660>>"
    )
    

    发现其背景视图名称变了,暗自高兴,这么容易就找到了,欢欢喜喜的修改了如下代码:

    if ([classname isEqualToString:@"_UINavigationBarBackground"] || [classname isEqualToString:@"UINavigationBarBackground"])
    
    // 将遍历子视图时的判断条件更改为
    if ([classname isEqualToString:@"_UINavigationBarBackground"] || [classname isEqualToString:@"UINavigationBarBackground"]||[classname isEqualToString:@"_UIBarBackground"])
    

    运行,结果却....还是不显示!!!
    再看断点处的bgView,确实也拿到了这个背景view,那是怎么回事呢?
    然后,使用可视化视图调试Debug View Hierarchy看了下视图的层次关系:
    在Xcode7.3-iOS9.3如下图:

    Xcode7.3-iOS9.3

    导航条的视图布局如下:

    导航条视图布局

    而在Xcode8-iOS10则变成这样了:

    Xcode8-iOS10层级关系

    而导航条的布局为:

    Xcode8导航条布局

    发现,添加的视图是存在的,但是为什么不显示呢?
    仔细观察两个视图的区别会发现,在Xcode8上,添加的视图上面还覆盖了一个视图UIVisualEffectView,而在Xcode7.3上这个模糊视图是不存在的,其实仔细观察未显示图片的导航条也会发现,隐隐约约能够看到一些下面图片颜色,这里就是中间有点灰色,这是因为这个模糊视图把下面的图片覆盖了,所以没有显示出来,这才是图片不显示的根本原因.

    解决问题

    找到原因了,修改代码就比较容易了,你可以在添加视图时,将bgView指定到UIVisualEffectView,将新的视图添加到UIVisualEffectView上:

    for (UIView  * v in subs)
        {
            NSString * classname = NSStringFromClass([v class]);
            if ([classname isEqualToString:@"_UINavigationBarBackground"] || [classname isEqualToString:@"UINavigationBarBackground"])
            {
                
                bgview=v;
                break;
            }  else if ([classname isEqualToString:@"_UIBarBackground"]) {
                //适配iOS10导航
                for (UIView *vi in v.subviews) {
                    
                    NSString *viName = NSStringFromClass([vi class]);
                    if ([viName isEqualToString:@"UIVisualEffectView"]) {
                        
                        bgview = vi;
                        break;
                    }
                }
            }
        }
    

    也可以还添加到_UIBarBackground上,但是找到UIVisualEffectView,将其隐藏掉:

    if ([classname isEqualToString:@"_UINavigationBarBackground"] || [classname isEqualToString:@"UINavigationBarBackground"])
            {
                
                bgview=v;
                break;
            } else if ([classname isEqualToString:@"_UIBarBackground"]) {
                
                bgview = v;
                
                for (UIView *vi in v.subviews) {
                    // 适配iOS10
                    NSString *viName = NSStringFromClass([vi class]);
                    if ([viName isEqualToString:@"UIVisualEffectView"]) {
                        
                        vi.hidden = YES;
                        break;
                    }
                }
            }
    

    再运行,会发现,问题解决:

    Xcode8-iOS10

    到此这个问题就解决完毕,如果有其他的解决途径,还请不吝赐教,感谢!!!

    (完)

    Github LQQZYY
    CSDN博客 流火绯瞳
    新浪微博 杯水_沧海
    QQ 302934443

    相关文章

      网友评论

          本文标题:[iOS10]Xcode8系统导航适配

          本文链接:https://www.haomeiwen.com/subject/cfikyttx.html