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

时间:2016-03-26 23:03:52

标签: ios swift uinavigationcontroller

我在l=range(4) for n in [2,1,0]: #test values for numbers of points to cut print n,l[:len(l)-n] 中嵌入了三个视图控制器。 UINavigationController导航至FirstViewController,导航至SecondTableViewController

我遇到的问题是在ThirdDetailViewController中使用status bar方法自定义UINavigationBarscrollViewDidScroll的样式时,它还会覆盖其中的其他视图控制器它之后的堆栈以及所有状态栏样式。

有人知道如何阻止scrollViewDidScroll方法影响堆栈中的其他视图控制器吗?

FirstViewController

SecondTableViewController

SecondTableViewController

我根据用户滚动到内容的多少或者从内容中脱颖而出来改变导航的样式。

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

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

}

ThirdDetailViewController

 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
    }
}

2 个答案:

答案 0 :(得分:1)

这是由(UIKit框架)设计的。

您的层次结构如下:

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

在其堆栈内托管

  • FirstViewController
  • SecondTableViewController
  • ThirdDetailViewController

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

这意味着你所有的三个控制器都指向了同一个导航控制器。 合理的是,对.navigationController进行更改并不重要 - 因为它总是相同且唯一的导航控制器只有一个导航栏,如果您推送或弹出任何将控制器视图到导航堆栈,您仍会看到为导航栏应用的最新样式。

您的解决方案是在EACH控制器中处理EXPLICITLY的导航栏样式。

BONUS TRACK:

您可以将导航栏样式提取到UIViewController扩展中。 您可以使用名为setNavigationStyle的方法,定义带有一些样式案例的枚举NavigationStyle,为方法内的每个案例实现样式,然后在viewWillAppear内的任何视图控制器中实现..只需调用{{1 }}管他呢。 这将很好地扩展,因为你可能有3个样式,但有14个控制器。这样可以防止重复样式实现​​,并使代码可重用。

答案 1 :(得分:1)

也可以在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

}