Reputation: 1809
Anyone know how to deal with this? Seems as though when you have a UIHostingController with a NavigationView the following happens:
Notice the big grey tab bar safe area.
This is primarily a UIKit application. Were replacing on of our tabs in the tab bar with A swiftUI view.
here is my code:
var body: some View {
NavigationView {
ZStack {
MapKitMapView(
mapView: mapView,
annotations: $annotations,
polylines: $polylines,
centerCoordinate: $centerCoordinate,
newMapRegion: $newMapRegion,
userTrackingMode: $userTrackingMode
)
.edgesIgnoringSafeArea(.all)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
ButtonLayer(mapView: mapView, userTrackingMode: $userTrackingMode, showSheet: $showSheet)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.padding(.margin)
}
.edgesIgnoringSafeArea(.all)
.navigationBarHidden(true)
.sheet(isPresented: $showSheet) {
SettingsView()
}
}
}
pardon the censorship. I want the app to remain anonymous.
But essentially my UITabBar is built as follows:
I have tried manually setting additional safe area insets to the UIHostingController to make it expand outside of the safe area.
If I remove the NavigationView everything looks and functions as intended.
Upvotes: 6
Views: 4936
Reputation: 21
self.tabBarController?.tabBar.isTranslucent = true
Worked for me.
Upvotes: 0
Reputation: 109
This is how I fixed a similar problem.
let vc = UIHostingController(rootView: MyView())
vc.navigationItem.title = "Title"
return UINavigationController(rootViewController: vc)
Upvotes: 3
Reputation: 818
This situation happens when you embed UIHostingController in UITabBar. To remove this gray line, just set the translucency of the UITabBar.
tabBar.isTranslucent = true
Upvotes: 2
Reputation: 1809
I found a workaround for this issue. However, I would like to use a pure swiftUI solution rather than the below workaround. So I am leaving this open to see if someone else has some other insight.
Upon inspecting the view hierarchy debugger, I noticed the following:
The navigation view style is SplitView... which is an iPad style. I am not actually setting my style. So maybe a bug is causing it to default to that.
I tried changing the NavigationView styling to StackNavigationViewStyle().
While this didn't fix the problem, It did cleanup the view hierarchy and wrap my UIHostingViewController in a proper UINavigationController.
It also changed the bottom grey "safe area" to white.
What this tells me, is that NavigationView just wraps your view in a standard UINavigationController when its being used in a UIHostingController. And since im interfacing with UIKit, maybe it makes more sense to set the root of my tab bar to a UINavigationController rather than a UIHostingController with a NavigationView inside of it.
So the tab that was experiencing the issue is now being populated with:
UINavigationController(rootViewController: UIHostingController(rootView: MyView()))
and my view code is just:
ZStack {
MapKitMapView(
mapView: mapView,
annotations: $annotations,
polylines: $polylines,
centerCoordinate: $centerCoordinate,
newMapRegion: $newMapRegion,
userTrackingMode: $userTrackingMode
)
.edgesIgnoringSafeArea(.all)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
ButtonLayer(mapView: mapView, userTrackingMode: $userTrackingMode, showSheet: $showSheet)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.padding(.margin)
}
.edgesIgnoringSafeArea(.all)
.navigationBarHidden(true)
.sheet(isPresented: $showSheet) {
SettingsView()
}
This actually corrected the issue. And I am able to push views without any problems using NavigationLinks.
I guess the lesson to learn here is:
SwiftUI interfaces with UIKit better than I thought.
What I still don't know is: Why was NavigationView having this problem if it just wraps your view in a UINavigationController? I tried reproducing it in a clean project and had no luck. So I suspect something being done in our app to customize the navigation bar or tab bar is causing this issue.
After much digging I could not find a root cause. So this workaround will have to suffice for the time being.
Upvotes: 9