My app has a main UITabBarController with 5 tabs (each one is a UINavigationController). The tabs contain various UI elements, such as UITableViews (with and without custom cells), UISegmentedControls, and others. When a view/tab is visible on screen and I rotate the device, the layout is adjusted as expected and everything works fine. However, now I do the following:
- Go to any tab, say tab A
- Navigate to another tab, say tab B
- While still on tab B, rotate device, for example from portrait to landscape
- Go back to tab A while still in the new orientation
The layout of the view of tab A is now messed up. For example, there is a huge margin on top of the tableview, or the UISegmentedControl is not visible at all. For the case of the UITableView, the layout finally updates when I scroll for a bit. For other views, the only possibility to get the correct layout is to rotate the device again when the view is visible.
Some of the views are created programmatically, some in storyboard. So it does not seem to matter which method is chose, the problem exists in both. A similar question can be found
select Tab2:
rotate device:
select Tab1:
As we see, there is a "gap" above the label.
Now, edit viewWillAppear()
in TabOneNavigationController
:
override func viewWillAppear(_ animated: Bool) {
// add this line to fix the layout problem
super.viewWillAppear(animated)
if #available(iOS 13.0, *) {
let navBarAppearance = UINavigationBarAppearance()
navBarAppearance.configureWithOpaqueBackground()
navBarAppearance.titleTextAttributes = [.foregroundColor: UIColor.white]
navBarAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.white]
navBarAppearance.backgroundColor = .blue
navigationBar.standardAppearance = navBarAppearance
navigationBar.scrollEdgeAppearance = navBarAppearance
}
}
Run it again, and when we go back to Tab1:
As a side note: you can put your navBarAppearance
code inside viewDidLoad()
so it only runs once instead of every time you switch tabs.