之前开发自定义ios NavigaitonBar的时候遇到过一些显示上的问题,即在非NavigationController里面使用NavigationBar的时候,会出现navigation bar 不能通顶的问题(即不能将背景显示在通知栏下方),具体图示如下:
不通顶
之前也大概的查了一下,网上给出的大部分方案(如添加在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的通顶了
效果图如下:
修改后现在来分析下为什么 说之前网上给出的方案会有问题, 我们先来分析下UINavigationController 中UINavigationBar 的View的结构:
20181029152901229.png.jpeg可以看到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。
网友评论