Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
175 views
in Technique[技术] by (71.8m points)

objective c - NavigationBar delay updating barTintColor iOS10

Context:

Let's say we have one NavigationController and 2 viewControllers. ViewControllerA has a blue navigationBar, while ViewControllerB has a green one.

I set them up like so :

override func viewWillAppear(_ animated: Bool) {
        self.navigationController?.navigationBar.barTintColor = UIColor.blue    // Green if ViewController B
    }

It works well when I got from A to B, but when I return, the navigationBar teint is updated after. Like if it was set up in the viewDidAppear.

Expected:

The navigation bar should have its navigation bar color updated without delay.

Solutions tried:

  • I've seen this SO post, and I tried the solution. It worked, but would make the management of the navigation bar a lot more complex and painful. (in a real app)

  • I've tried to change the navbar teint in the ViewWillDisappear method. Didn't work.

More:

This is caused by a change on the ios10 API. I've read the release notes, but it's still unclear what should be done in this case.

In iOS 10, UIKit has updated and unified background management for UINavigationBar, UITabBar, and UIToolbar. In particular, changes to background properties of these views (such as background or shadow images, or setting the bar style) may kick off a layout pass for the bar to resolve the new background appearance.

In particular, this means that attempts to change the background appearance of these bars inside of layoutSubviews, -[UIView updateConstraints], viewWillLayoutSubviews, viewDidLayoutSubviews, updateViewConstraints, or any other method that is called in response to layout may result in a layout loop.

In some cases you can break these layout loops by ensuring that you always use the same object instance when objects (such as UIImage or UIColor) are required. But in general you should avoid doing this.

Question:

What would be the best way to handle the navigation bar changes between different navigation controllers in iOS 10 ?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Try this code:

Note: Code Tested in Swift 3.

In ViewController A:

    override var isViewLoaded: Bool {
    title = "View 1"
    navigationController?.navigationBar.barTintColor = .blue
    navigationController?.navigationBar.isTranslucent = true
    navigationController?.navigationBar.tintColor = UIColor.white
    navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName:UIColor.white]
    UIApplication.shared.statusBarStyle = .lightContent
    self.navigationController?.navigationBar.barStyle = .black // In case statusbar Light content wont work.
    return true
    }

In ViewController B:

    override var isViewLoaded: Bool {
    title = "View 2"
    navigationController?.navigationBar.barTintColor = .green
    navigationController?.navigationBar.tintColor = .white
    navigationController?.navigationBar.isTranslucent = true
    navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName:UIColor.white]
    return true
    }

Output: No delay what so ever...

enter image description here

Pattern Image as a TintColor.

In ViewController A:

 navigationController?.navigationBar.barTintColor = UIColor(patternImage: UIImage(named: "viewOneImage.jpg")!)

In ViewController B:

 navigationController?.navigationBar.barTintColor = UIColor(patternImage: UIImage(named: "viewTwoImage.jpg")!)

Output:

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...