【问题标题】:Changing navigation bar color while popping view controller弹出视图控制器时更改导航栏颜色
【发布时间】:2017-07-25 22:04:58
【问题描述】:

我有三个视图控制器。在第一个视图控制器 (FirstVC) 中,导航栏的 bar tint color 是 clearColor 并且 bar 本身是半透明的。当我点击某个东西时,我会推送到 SecondVC,其中导航栏需要是不透明的。所以我将 barTintColor 设置为某个颜色值并将 isTranslucent 设置为 false。当我从 SecondVC 推送到 ThirdVC 时,导航栏再次需要是半透明的。当我弹出 ThirdVC 并返回 SecondVC 时,问题就出现了。导航栏显示为透明一秒钟,然后根据需要变为不透明。我无法理解延迟的原因。

从 SecondVC 的viewWillAppear() 调用以下方法。我已经尝试从 ThirdVC 的viewWillDisappear()做同样的事情,但没有效果。

fileprivate func configureNavigationBar(){

        self.navigationController?.navigationBar.setBackgroundImage(nil, for: UIBarMetrics.default)
        self.navigationController?.navigationBar.shadowImage = nil
        self.navigationController?.navigationBar.isTranslucent = false
        self.navigationController?.navigationBar.barTintColor = Style.Movie.primaryBackgroundColor
        let titleDict: NSDictionary = [NSForegroundColorAttributeName: UIColor.white]
        self.navigationController?.navigationBar.titleTextAttributes = titleDict as? [String:Any]
    }

如果我向后滑动而不是点击返回按钮,它会正常工作。

【问题讨论】:

  • 你是否在弹回动画时制作动画??
  • 不,我没有做那种事。
  • 即使你设法实现了这一点,这样的用户界面也不会看起来很流畅。

标签: ios swift uinavigationbar


【解决方案1】:

您可以为 SecondVC 制作自定义导航栏。并在单击后退按钮时手动调用 -popViewController 方法。

【讨论】:

  • 这应该是评论,而不是答案。
【解决方案2】:

在thiredVC中使用这个函数

override func willMove(toParentViewController parent: UIViewController?) {
          self.navigationController?.navigationBar.barTintColor = color use in secondVC
    }

【讨论】:

  • 是的,这有效.. 只是我必须将 isTranslucent 属性以及 barTintColor 设置为 false。谢谢
  • 你救了我的命!非常感谢!
  • 最佳答案。谢谢
  • 这行得通,但为什么相同的代码在 viewDidDisappear 或 viewWillDisappear 中不起作用?为什么设置颜色是子视图控制器的责任而不是父视图控制器的责任?
  • 这对我有帮助!谢谢:)
【解决方案3】:

偶然发现了这个帖子,并想出了一个很好的解决方案来帮助未来的所有人。

首先创建一个自定义UINavigationController,其类型为enum,这将有助于定义您的导航设置:

enum NavType: Int {
    case light, medium, dark
}

class NavigationController: UINavigationController {

    /* 
      Fetch the last controller in the navigation stack so the 
      ViewControllers can switch the navType
    */
    var previousController: ViewController? {
        if viewControllers.count > 1 {
            return viewControllers[viewControllers.count-2] as? ViewController
        }
        return nil
    }

    var navType: NavType = .light {
        didSet { updateNavType() }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        navigationBar.isTranslucent = false
        layoutNavigationTheme()
    }

    func layoutNavigationTheme() {
        switch navType {
        case .dark:
            view.backgroundColor = .white
            navigationBar.backgroundColor = .black
            navigationBar.barTintColor = .black
            navigationBar.tintColor = .white

        ... // Set up as per enum
        }
    }

}

然后使用willMove(... 创建一个自定义UIViewController

class ViewController: UIViewController {

    var navType: NavType = .light

    var navigation: NavigationController? {
        return navigationController as? NavigationController
    }

    // Override willMove will fetch the last controller and set the navType
    override func willMove(toParentViewController parent: UIViewController?) {
        super.willMove(toParentViewController: parent)

        if let navigation = navigation {
            navigation.navType = navigation.previousController?.navType ?? .light
        }
    }

}

然后只需在您的 UIViewControllers 中,将您的新ViewController 子类化并在viewDidLoad 中设置navType

class MainController: ViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        navType = .dark
    }

}

【讨论】:

  • 不要只 c&p 大部分代码,花更多时间解释。也许至少先清理你的代码,==== 字符的评论块占了你发布的代码的一半。
  • 我还没有完成我发布的内容! @克劳斯约根森
【解决方案4】:

另一个可行的解决方案是覆盖 pushViewController(_ viewController: UIViewController, animated: Bool) 和 popViewController(animated: Bool) -> UIViewController? UINavigationController 的。

class CustomNC : UINavigationController {
    public override init(rootViewController: UIViewController) {
        super.init(rootViewController: rootViewController)
    }

    public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nil, bundle: nil)
    }

    public required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    private var isCustomDesign: Bool { 
        return viewControllers.count == 1 && viewControllers[0] is MyCustomVC // Or any other condition 
    }

    override func pushViewController(_ viewController: UIViewController, animated: Bool) {
        super.pushViewController(viewController, animated: animated)
        if isCustomDesign {
            navigationBar.barTintColor = UIColor.red
        } else {
            navigationBar.barTintColor = UIColor.green
        }
    }

    override func popViewController(animated: Bool) -> UIViewController? {
        let viewController = super.popViewController(animated: animated)
        if isCustomDesign {
            navigationBar.barTintColor = UIColor.red
        } else {
            navigationBar.barTintColor = UIColor.green
        }
        return viewController
    }
}

【讨论】:

    【解决方案5】:
    override func viewWillAppear(_ animated: Bool)
    

    您可以在执行顶部视图控制器弹出操作时调用的函数内设置视图属性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-09
      • 2016-01-14
      • 1970-01-01
      相关资源
      最近更新 更多