In my app's navigation controller, I want to push a view controller with a clear navigation bar and toolbar. When the first view controller appears again, I want the navigation bar and toolbar to have their default appearances again.
I turned on Slow Animations in the simulator settings so you can see how it looks:
The areas above the navigation bar and underneath the home indicator don't look quite right during the transition because there's nothing there, while the actual navigation bar and toolbar fade out.
Also, when popping the controller, the toolbar appears instantly. This especially looks bad when dismissing it interactively with the swipe back gesture.
I might be able to get it to look good using the new UIBarAppearance
classes in iOS 13, but I want to continue to support older versions of iOS.
This is the code I have so far. These methods are inside the detail view controller. Also I don't want to really set the background color to white, but get the default blurred appearance, even in dark mode, but am not sure what to set it back to.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
func doThings() {
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationController?.navigationBar.shadowImage = UIImage()
navigationController?.navigationBar.backgroundColor = .clear
navigationController?.navigationBar.barTintColor = .clear
navigationController?.toolbar.setBackgroundImage(UIImage(), forToolbarPosition: .bottom, barMetrics: .default)
navigationController?.toolbar.setShadowImage(UIImage(), forToolbarPosition: .bottom)
navigationController?.toolbar.backgroundColor = .clear
navigationController?.toolbar.barTintColor = .clear
}
guard self.navigationController?.topViewController === self else { return }
let animationsWereQueuedSuccessfully = self.transitionCoordinator?.animate(alongsideTransition: { [weak self] context in
guard self != nil else { return }
doThings()
}, completion: nil)
if animationsWereQueuedSuccessfully != true {
doThings()
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
func doThings() {
navigationController?.navigationBar.setBackgroundImage(nil, for: UIBarMetrics.default)
navigationController?.navigationBar.shadowImage = nil
navigationController?.navigationBar.backgroundColor = .white
navigationController?.navigationBar.barTintColor = .white
navigationController?.toolbar.setBackgroundImage(nil, forToolbarPosition: .bottom, barMetrics: .default)
navigationController?.toolbar.setShadowImage(nil, forToolbarPosition: .bottom)
navigationController?.toolbar.backgroundColor = .white
navigationController?.toolbar.barTintColor = .white
}
let animationsWereQueuedSuccessfully = self.transitionCoordinator?.animate(alongsideTransition: { [weak self] context in
guard self != nil else { return }
doThings()
}, completion: nil)
if animationsWereQueuedSuccessfully != true {
doThings()
}
}