iOS UINavigationBar button remains faded after segue back
In my app I have multiple view controllers, and most have a right-hand-side UIBarButtonItem
with direct "show" segue actions attached.
Having segued to another view and then pressed the '< Back'
button, the original button item remains faded out, although still otherwise usable.
This only appears to happen under iOS 11.2.
I can't see any setting that could be doing this, and in at least one of the cases where this happens there's no specific segue unwinding nor viewDidAppear
handling. I'd post some code, but AFAICS it's all just default UINavigationBar
behaviour.
Solution 1:
This is a bug in iOS 11.2 and happens because the UIBarButtonItem
stays highlighted after navigation and does not return to its normal state after the other view controller pops.
To avoid this behavior, either
use a
UIBarButtonItem
with aUIButton
as a custom view-
disable and re-enable the bar button item in
viewWillDisappear(_:)
(although this causes the button to appear immediately, use matt's solution to avoid this):barButtonItem.isEnabled = false barButtonItem.isEnabled = true
Solution 2:
What I do is work around this bug, in the view controller's viewWillAppear
, as follows:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.navigationBar.tintAdjustmentMode = .normal
self.navigationController?.navigationBar.tintAdjustmentMode = .automatic
}
That seems to wake up the button without visual artifacts.
Solution 3:
Another work around is to implement the fix on the parent navigationController - so that each of its child viewController's gets the fix as follows
NOTE: This requires the receiving class to be setup as the UINavigationController delegate
Swift
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
if #available(iOS 11.2, *) {
navigationBar.tintAdjustmentMode = .normal
navigationBar.tintAdjustmentMode = .automatic
}
}
Objective-C
-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if (@available(iOS 11.2, *)) {
self.navigationBar.tintAdjustmentMode = UIViewTintAdjustmentModeNormal;
self.navigationBar.tintAdjustmentMode = UIViewTintAdjustmentModeAutomatic;
}
}
Solution 4:
I solved it like this:
override func viewWillDisappear(_ animated: Bool) {
navigationController?.navigationBar.tintAdjustmentMode = .normal
navigationController?.navigationBar.tintAdjustmentMode = .automatic
}
so it will restore the color before the other view appear