IOS自定义NavigationBar通顶的问题

之前开发自定义ios NavigaitonBar的时候遇到过一些显示上的问题,即在非NavigationController里面使用NavigationBar的时候,会出现navigation bar 不能通顶的问题(即不能将背景显示在通知栏下方),具体图示如下:

IOS自定义NavigationBar通顶的问题_第1张图片

之前也大概的查了一下,网上给出的大部分方案(如添加在status bar 下面添加一个view,或直接改变UInavigationBar的frame等等),我认为并不能很好的解决这个问题。

进过查阅苹果的api后,发现一个delegate:UIBarPositioningDelegate,这个类是UINavigationBarDelegate的基类。先将问题的解决方案抛出,再解释下为什么网上给出的方案本人并不认同。

方案(swift):

首先设置自定义的NavigaitonBar的delegate,即:

navigationBar.delegate = self

(其中self实现UINavigationBarDelegate)

再实现下面的代理方法:

func position(for bar: UIBarPositioning) -> UIBarPosition {

        return .topAttached

 }

就可以很简单的实现UINavigationBar的通顶了

效果图如下:

IOS自定义NavigationBar通顶的问题_第2张图片

 

现在来分析下为什么 说之前网上给出的方案会有问题, 我们先来分析下UINavigationController 中UINavigationBar 的View的结构:

IOS自定义NavigationBar通顶的问题_第3张图片

可以看到NavigationBar的Frame和背景的Frame是不同的。也就是说 系统的默认实现 并没有改变NavigationBar大小。只不过是在navigationBar的后方添加了一个layer。作为background layer 通过改变layer的颜色来实现通顶。

那么对比网上的两个方法。

1.在status部分添加一个view 同步改变view的颜色。

这个方法的问题在于代码内聚性过低。而且NavigationBar的背景层有blur效果。如果添加会导致,如果更改颜色需要同时更改两个地方,且statusbar下面的view还不能直接使用UIView,而是Visual effect view with blur。

 

2.直接改变navigationbar 的frame使其通顶。

这个方案更不推荐因为,这样会改变navigationbar 的坐标原点。 导致内部的navigationItem发生位移。

其他的小众方案就不细谈了。

其实苹果在delegate 中为我们留出了。NavigationBar通顶的方法,所以最好直接使用官方的api,这样以后的兼容性会更好。关于NavigationBar通顶的问题就说到这里。其实是个很小的问题。但是看到国内网站上的解决方案都有点蹩脚。所以专门写一篇文章来说明下这个官方api。

你可能感兴趣的:(移动开发,IOS,UINavigationBar)