为了保持UI风格的一致,有时可能需要在非UINavigationController的子控制器中添加导航栏,如下图。
系统的导航栏会使状态栏的颜色与之一致,而手动添加的导航栏则不会。虽然可以通过更改视图的背景颜色实现一致,但这太山寨了,既然如此,我为什么不直接拖两个button和一个label做个假的navigation bar呢?
仔细观察,不难发现UINavigationBar和UISearchBar的delegate都遵循一个名为
UIBarPositioningDelegate
的协议,这个协议只有一个方法,如下。
public protocol UIBarPositioningDelegate : NSObjectProtocol {
/* Implement this method on your manual bar delegate when not managed by a UIKit controller.
UINavigationBar and UISearchBar default to UIBarPositionTop, UIToolbar defaults to UIBarPositionBottom.
This message will be sent when the bar moves to a window.
*/
@available(iOS 7.0, *)
optional public func position(for bar: UIBarPositioning) -> UIBarPosition // UINavigationBarDelegate, UIToolbarDelegate, and UISearchBarDelegate all extend from this
}
我们只要给我们的导航栏或者搜索栏设置代理,并在代理中实现这个方法就可以让状态栏的颜色与它们一致了。
func position(for bar: UIBarPositioning) -> UIBarPosition {
return .topAttached
}
如下图。
如果设置以后没有达到预期的效果,请检查:
1.是否希望使状态栏和导航栏的backgroundColor
颜色一致。决定状态栏颜色的是导航栏的barTintColor
属性。
2.导航栏的isTranslucent
属性是否为true
,如果是,你怎么设置barTintColor也不会改变导航栏或状态栏的颜色。
3.是否在storyboard中设置导航栏的颜色。如果你发现在storyboard中设置导航栏的颜色无效,很可能是你曾经修改过UINavigationBar.appearance
,只要在代码适当位置(如viewDidLoad
中)直接设置导航栏的相关属性即可。
搜索栏同理。