[iOS10]Xcode8系统导航适配

开发环境

Xcode 8
iOS 10

Xcode 7.3
iOS9.3

问题

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


导航中间位置有一个LOGO视图(当然不是这个条形码),而在Xcode8-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如下图:


导航条的视图布局如下:


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


而导航条的布局为:


发现,添加的视图是存在的,但是为什么不显示呢?
仔细观察两个视图的区别会发现,在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;
                }
            }
        }

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


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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值