简体   繁体   中英

NavigationBar title text won't change with titleTextAttributes

I have a strange issue which I don't really understand.

I have two views, one should have a black title and the other should have a white title.

The issue that I am experiencing is that I can set the color ONCE and not change it back.

So when I go to the view that has the white title from the view with the black title and then go back, the title does not change back to black.

code for white title in viewWillAppear:

self.navigationController?.navigationBar.barStyle = .black
self.navigationController?.navigationBar.tintColor = .white
self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]

code for black title in viewWillAppear:

self.navigationController?.navigationBar.isHidden = false
self.navigationController?.navigationBar.barStyle = .default
self.navigationController?.navigationBar.tintColor = UIColor.blue
self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.black]

Why does it not change back, when I am clearly setting a new color?

EDIT: adding the complete code

Black title view:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.navigationController?.navigationBar.isHidden = false
    self.navigationController?.navigationBar.barStyle = .default
    self.navigationController?.navigationBar.tintColor = hexStringToUIColor(hex: "4CAF50")
    self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.black]
    self.navigationItem.title = listData.name

    clearStatusBarColor()

    let editButton = UIBarButtonItem(title: "Edit", style: .plain, target: self, action: #selector(tapToEdit))
    let sortImg = UIImage(named: "sort")
    sortingButton = UIBarButtonItem(image: sortImg, style: .plain, target: self, action: #selector(tapToSort))
    self.navigationItem.rightBarButtonItems = [sortingButton!, editButton]

    self.navigationController?.navigationBar.setBackgroundImage(nil, for: UIBarMetrics.default)
    self.navigationController?.navigationBar.shadowImage = nil

    // get updated Data
    if User.active.hasListUpdated {
        // return with new gameEntries -> Update
        listData = User.active.allLists![listDataIndex] // To keep upToDate data!

        listEntries = listData.list_entries!

        gameEntries = listEntries.compactMap({ (entry: ListEntry) -> GameEntry in
            return GameEntry(game: entry.game, platform: nil, platform_id: entry.platform, rating: Int(entry.rating ?? 0), review: nil, notes: entry.description)
        })

        listTable.reloadData()
    }

    // Sorting
    if hasSortChanged {
        hasSortChanged = false
        sortList(sort: sortingOption, order: sortingOrder)
    }
}

White title view:

    override func viewWillAppear(_ animated: Bool) {
    if !isPreviewing {
        self.navigationController?.navigationBar.isHidden = false
        self.navigationController?.navigationBar.barStyle = .black
        self.navigationController?.navigationBar.tintColor = .white
        self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]

        // MARK: Clear StatusBar
        clearStatusBarColor()

        if transparentNav {
            self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for:UIBarMetrics.default)
            self.navigationController?.navigationBar.shadowImage = UIImage()
            self.title = nil
        } else {
            self.navigationController?.navigationBar.setBackgroundImage(nil, for: UIBarMetrics.default)
            self.navigationController?.navigationBar.shadowImage = nil
            self.title = game.name!
        }
    }

    // MARK: NavigationBar
    let button = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(showOptions))
    self.navigationItem.rightBarButtonItem = button


    // Check if game should have new review or rating
    if User.active.hasMainScreenUpdated {
        // Update rating
        updateUserRating()
        // update review
        updateUserReviewStatus()
    }

    // Update lists! 
    if User.active.hasListUpdated {
        updateListsStatus()
    }

}

If you are changing the nav bar colors in different view controllers, I recommend you to have a subclass of UIViewController and handle the navbar changes through that. Here's an example for your case.

class CustomUIViewController: UIViewController {

    override func didMove(toParentViewController parent: UIViewController?) {
        super.didMove(toParentViewController: parent)
        if parent == nil {
            if SettingsManager.LastBarColor == .default {
                self.setLightBars()
            }
            else {
                self.setDarkBars()
            }
        }
    }

    func setDarkBars() {
        SettingsManager.LastBarColor = .lightContent
        UIApplication.shared.statusBarStyle = UIStatusBarStyle.lightContent
        tabBarController?.tabBar.tintColor = UIColor.white
        navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
    }

    func setLightBars() {
        SettingsManager.LastBarColor = .default

        UIApplication.shared.statusBarStyle = UIStatusBarStyle.default
        tabBarController?.tabBar.tintColor = UIColor.Black
        navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor:UIColor.Black]
        navigationController?.navigationBar.barTintColor = UIColor.white
        navigationItem.titleView?.tintColor = UIColor.Black
    }
}

class SettingsManager {

    class var LastBarColor: UIStatusBarStyle = .default

}

And in your view controller use CustomUIViewController, call setDarkBars() or setLightBars() in your viewWillAppear() function.

You can use a custom UINavigationController class then override pushViewController function to set what you need on the navigationBar.

The viewWillAppear method has a lot of code here.

class MyNavigationViewController: UINavigationController {
    override func pushViewController(_ viewController: UIViewController, animated: Bool) {
        super.pushViewController(viewController, animated: animated)
        self.updateForVC(viewController: viewController)

    }

    func updateForVC(viewController: UIViewController) {
        //DO WHATEVER YOU WHANT HERE, title, img, etc

        var color = UIColor.black

        if viewController.isKind(of: MyClass.self) {
            color = UIColor.white
        }

        self.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: color]
    }

}   

Try pushViewController to navigate,It is working for me

if let viewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SecondViewController") as? SecondViewController {
      if let navigator = self.navigationController {
        navigator.pushViewController(viewController, animated: true)
       viewController.title = ""
      }
    }

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