简体   繁体   中英

UINavigationBarAppearance update after view controller has appeared

It seems that there is no – or at least no obvious – way to update navigation styles on a view controller when using the new UINavigationBarAppearance apis . Whilst these APIs are far superior to the old styling methods, in particular when wanting a transparent navigation bar, I have a need in multiple apps to be able to switch between a transparent navigation and opaque one.

Does anyone know a workaround for this? Or something I might be missing? Example code below!

var styles: [UINavigationBarAppearance] = {

    let style1 = UINavigationBarAppearance()
    style1.configureWithOpaqueBackground()
    style1.backgroundColor = .white
    style1.titleTextAttributes = [.foregroundColor: UIColor.black]
    style1.largeTitleTextAttributes = [.foregroundColor: UIColor.black]

    let buttonAppearance = UIBarButtonItemAppearance()
    buttonAppearance.normal.titleTextAttributes = [
        .foregroundColor: UIColor.black
    ]
    style1.buttonAppearance = buttonAppearance

    let style2 = UINavigationBarAppearance()
    style2.configureWithOpaqueBackground()
    style2.backgroundColor = .systemBlue
    style2.titleTextAttributes = [.foregroundColor: UIColor.systemGreen]
    style2.largeTitleTextAttributes = [.foregroundColor: UIColor.systemGreen]

    let button2Appearance = UIBarButtonItemAppearance()
    button2Appearance.normal.titleTextAttributes = [
        .foregroundColor: UIColor.systemGreen
    ]
    style2.buttonAppearance = button2Appearance

    let style3 = UINavigationBarAppearance()
    style3.configureWithTransparentBackground()
    style3.titleTextAttributes = [.foregroundColor: UIColor.systemBlue]
    style3.largeTitleTextAttributes = [.foregroundColor: UIColor.systemBlue]

    let button3Appearance = UIBarButtonItemAppearance()
    button3Appearance.normal.titleTextAttributes = [
        .foregroundColor: UIColor.systemBlue
    ]
    style3.buttonAppearance = button3Appearance

    return [style1, style2, style3]

}()

var currentStyle: UINavigationBarAppearance?

override func viewDidLoad() {

    currentStyle = styles.first
    super.viewDidLoad()
    // Do any additional setup after loading the view.
}

@IBAction func switchNavigavigationStyles(_ sender: Any) {

    guard let currentStyle = currentStyle else {
        return
    }
    guard let styleIndex = styles.firstIndex(of: currentStyle) else {
        return
    }

    var nextIndex = styleIndex + 1
    if nextIndex == styles.count {
        nextIndex = 0
    }

    navigationController?.navigationBar.scrollEdgeAppearance = styles[nextIndex]
    navigationController?.navigationBar.compactAppearance = styles[nextIndex]
    navigationController?.navigationBar.standardAppearance = styles[nextIndex]
    navigationController?.navigationBar.setNeedsDisplay() // Attempting to force it to redraw!
    navigationController?.view.setNeedsDisplay()

    self.currentStyle = styles[nextIndex]
}

Got it! So after re-watching the WWDC video it seems like to configure on a particular screen you set navigationItem.standardAppearance etc. Have attempted to use this instead, and it seems to do the job!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM