NavigationBar标题颜色切换异常:返回时未恢复为白色
Hey, I’ve looked over your code and spotted the issue—when popping back to your root ViewController, the title color isn’t switching back to white because your style updates are wrapped exclusively in transitionCoordinator?.animate(alongsideTransition:). This closure might not fire reliably during the pop transition, leaving the old (black) title color stuck.
The Root Cause
The willShow method does get called when returning to the root controller, but relying solely on the transition coordinator’s animation block means if the coordinator isn’t available (or the animation callback doesn’t trigger as expected), your navigation bar styles never get updated back to the root controller’s white title and cyan background.
The Fix
We’ll refactor the code to ensure style updates happen whether there’s a transition animation or not. Here’s the adjusted version of your navigationController(_:willShow:animated:) method:
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) { let isSettingsContainer = viewController is ViewController let backgroundColor = isSettingsContainer ? UIColor.cyan : UIColor.white let titleColor = isSettingsContainer ? UIColor.white : UIColor.black let image = isSettingsContainer ? UIImage() : nil navigationController.navigationBar.shadowImage = image navigationController.navigationBar.setBackgroundImage(image, for: .default) // Extract style updates into a reusable closure let updateNavigationBarStyle = { navigationController.navigationBar.tintColor = titleColor navigationController.navigationBar.barTintColor = backgroundColor navigationController.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor : titleColor] } // Apply styles with animation if possible, otherwise apply immediately if let coordinator = navigationController.transitionCoordinator, animated { coordinator.animate(alongsideTransition: { _ in updateNavigationBarStyle() }) } else { updateNavigationBarStyle() } // Trigger status bar style update to match the current controller setNeedsStatusBarAppearanceUpdate() }
What Changed?
- Reusable Style Closure: We moved all the navigation bar style logic into a closure so we can reuse it across both animated and non-animated scenarios.
- Fallback for No Coordinator: If there’s no transition coordinator (or the transition isn’t animated), we apply the styles directly instead of relying on the animation block. This ensures the root controller’s styles are set when popping back.
- Status Bar Update: Added
setNeedsStatusBarAppearanceUpdate()to make sure the status bar style switches back correctly alongside the navigation bar changes.
This should fix the issue—now when you pop back to the root ViewController, the title color will revert to white as expected, along with the cyan navigation bar background.
内容的提问来源于stack exchange,提问作者Sonius

