【发布时间】:2018-02-20 12:14:41
【问题描述】:
我想在 iOS 11 大标题更改时获取该事件。即当用户滚动视图时,它将位置更改为导航栏和导航栏。我已经检查了 UINavigationBar 类,但我无法从中得到它。
我想要实现的屏幕设计就像当大标题可见时我想要透明导航栏但当标题向上滚动到导航栏时我想要纯色导航栏。
【问题讨论】:
标签: ios uinavigationbar ios11
我想在 iOS 11 大标题更改时获取该事件。即当用户滚动视图时,它将位置更改为导航栏和导航栏。我已经检查了 UINavigationBar 类,但我无法从中得到它。
我想要实现的屏幕设计就像当大标题可见时我想要透明导航栏但当标题向上滚动到导航栏时我想要纯色导航栏。
【问题讨论】:
标签: ios uinavigationbar ios11
可以通过scrollViewDidScroll函数获取UINavigationBar的当前高度。
func scrollViewDidScroll(_ scrollView: UIScrollView) {
//Get current height of navigation bar when tableview/collectionview/scrollview did scroll
guard let navBarHeight = navigationController?.navigationBar.frame.height else {
return
}
//Compare with standard height of navigation bar.
if navBarHeight > 44.0 {
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.barTintColor = .clear
} else {
self.navigationController?.navigationBar.shadowImage = nil
self.navigationController?.navigationBar.setBackgroundImage(nil, for: .default)
self.navigationController?.navigationBar.barTintColor = .green
}
}
【讨论】:
我已经在我的 UIViewController 的子类的 ViewWillAppear 中添加了这个观察者。并根据其高度设置颜色如下:
在 ViewWillAppear 中:
UINavigationBar *navBar = self.navigationController.navigationBar;
[navBar addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
在视图中将消失:
UINavigationBar *navBar = self.navigationController.navigationBar;
[navBar removeObserver:self forKeyPath:@"frame" context:NULL];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if ([keyPath isEqualToString:@"frame"]) {
[self setNavigationBarColour];;
}
}
- (void)setNavigationBarColour
{
UINavigationBar *navBar = self.navigationController.navigationBar;
CGFloat height = navBar.bounds.size.height;
if(height>44)
{
[navBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
[navBar setTranslucent:YES];
[navBar setShadowImage:[UIImage new]];
}
else
{
[navBar setBackgroundImage:[[UINavigationBar appearance] backgroundImageForBarMetrics:UIBarMetricsDefault] forBarMetrics:UIBarMetricsDefault];
[navBar setTranslucent:NO];
[navBar setShadowImage:[[UINavigationBar appearance] shadowImage]];
}
}
【讨论】:
layoutSubviews:这样您仍然可以观察到大标题何时更改其可见性,并且您对setNavigationBarColour 的调用会更少.
对 Piyush Hirpara 答案的一个小改进(关于性能)是子类化您的 navigationBar 并且仅在 layoutSubviews 上更新:
class ObservingLargeTitleNavigationBar: UINavigationBar {
override func layoutSubviews() {
super.layoutSubviews()
updateLargeTitle()
}
private func updateLargeTitle() {
if #available(iOS 11.0, *) {
if frame.height > 44 {
// code logic when large title is visible
} else {
// code logic when large title is hidden
}
}
}
}
请注意,frame.height 的44 的值在某些情况下可能需要调整。我在60 有它,例如在我的 iPhone X 配置中。
【讨论】: