在单独的View Controller上使用scrollViewDidScroll时,无法更改UINavigationBar的样式

我在UINavigationControllerembedded了三个视图控制器。 FirstViewController导航到SecondTableViewController ,导航到ThirdDetailViewController

我遇到的问题是当使用scrollViewDidScroll方法自定义status barUINavigationBar的风格时,它也覆盖堆栈中的其他视图控制器以及所有状态栏样式。

有谁知道我可以如何防止scrollViewDidScroll方法影响堆栈中的其他视图控制器?

FirstViewController

 override func viewWillAppear(animated: Bool) { UIApplication.sharedApplication().statusBarStyle = .Default self.navigationController?.navigationBar.setBackgroundImage(UIImage(), forBarPosition: .Any, barMetrics: .Default) self.navigationController?.navigationBar.shadowImage = UIImage() self.navigationController?.navigationBar.backgroundColor = UIColor.whiteColor() self.navigationController?.navigationBar.tintColor = UIColor.blackColor() self.navigationController?.navigationBar.barTintColor = UIColor.whiteColor() self.navigationController?.navigationBar.translucent = true } 

SecondTableViewController

我改变了导航的风格,取决于用户滚动了多less,以融入或脱离内容。

其他视图控制器的样式将更改为方法中设置的任何样式。

  override func scrollViewDidScroll(scrollView: UIScrollView) { let color = colorWheel() if (scrollView.contentOffset.y > -60) { UIApplication.sharedApplication().statusBarStyle = .Default self.navigationController?.navigationBar.setBackgroundImage(nil, forBarMetrics: UIBarMetrics.Default) self.navigationController?.navigationBar.shadowImage = UIImage() self.navigationController?.navigationBar.backgroundColor = UIColor.whiteColor() self.navigationController?.navigationBar.tintColor = color.appColor self.navigationController?.navigationBar.barTintColor = UIColor.whiteColor() self.navigationController?.view.backgroundColor = color.appColor self.navigationController?.navigationBar.translucent = true } else { UIApplication.sharedApplication().statusBarStyle = .LightContent self.navigationController?.navigationBar.setBackgroundImage(UIImage(), forBarMetrics: UIBarMetrics.Default) self.navigationController?.navigationBar.shadowImage = UIImage() self.navigationController?.navigationBar.backgroundColor = UIColor.clearColor() self.navigationController?.navigationBar.tintColor = UIColor.whiteColor() self.navigationController?.navigationBar.barTintColor = UIColor.clearColor() self.navigationController?.view.backgroundColor = UIColor.clearColor() self.navigationController?.navigationBar.translucent = true } } 

ThirdDetailViewController

 override func viewWillAppear(animated: Bool) { UIApplication.sharedApplication().statusBarStyle = .Default self.navigationController?.navigationBar.setBackgroundImage(UIImage(), forBarPosition: .Any, barMetrics: .Default) self.navigationController?.navigationBar.shadowImage = UIImage() self.navigationController?.navigationBar.backgroundColor = UIColor.whiteColor() self.navigationController?.navigationBar.tintColor = UIColor.blackColor() self.navigationController?.navigationBar.barTintColor = UIColor.whiteColor() self.navigationController?.navigationBar.translucent = true } 

更改viewDidAppear方法内的导航属性。

 override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) UIApplication.sharedApplication().statusBarStyle = .Default UIApplication.sharedApplication().statusBarStyle = .Default self.navigationController?.navigationBar.setBackgroundImage(UIImage(), forBarPosition: .Any, barMetrics: .Default) self.navigationController?.navigationBar.shadowImage = UIImage() self.navigationController?.navigationBar.backgroundColor = UIColor.whiteColor() self.navigationController?.navigationBar.tintColor = UIColor.blackColor() self.navigationController?.navigationBar.barTintColor = UIColor.whiteColor() self.navigationController?.navigationBar.translucent = true } 

这是通过(UIKit框架)devise的。

你的层次是这样的:

  • 导航控制器 (带有导航栏)

托pipe在其内部

  • FirstViewController
  • SecondTableViewController
  • ThirdDetailViewController

任何UIViewController的子类,也意味着你的控制器inheritance了一个名为.navigationController.的属性.navigationController. 这只是指向哪个导航控制器托pipe视图控制器。

这意味着你所有的三个控制器指向相同的导航控制器。 这是合乎逻辑的,这并不重要,你做的改变.navigationController – 因为它总是相同的,唯一的导航控制器与一个唯一的导航栏 ,如果你推或popup任何视图控制器的导航堆栈,你仍然会查看您应用于导航栏的最新样式。

您的解决scheme是在每个控制器中处理导航栏的样式。

奖金追踪:

您可以将导航栏样式提取到UIViewController扩展中。 你可以有一个名为setNavigationStyle的方法,用一些样式的case来定义一个枚举NavigationStyle,在方法内部为每个case实现样式,然后在viewWillAppear里面的任何视图控制器中调用setNavigationStyle: .Dark或者其他东西。 这将很好地扩展,因为你可能有3个风格,但14个控制器。 通过这种方式,您可以避免重复使用样式,并使代码可重用。