'UITabBar containing SwiftUI View
I have the below series of controllers and views. However, when I use the navigation link on the MoreView it changes the tabBarItem.title value. For instance it will say more, but when the privacy policy button is clicked and the user is navigated to policy view, the title in the tab bar changes to whatever is in .navigationBarTitle() or if non is provided, an empty string! How do I avoid this? I want the tab bar title to be static
UITabBar -> UINavigationController -> MoreViewController(UIHostingController) -> MoreView(SwiftUI)
MoreView
List {
Section(
header: Text("ABOUT"),
footer: Text(aboutFooter)
.font(.caption)
) {
NavigationLink(destination: WebView(
request: URLRequest(url: URL(string: "https://www.websitepolicies.com/policies/view/ng0sNvAJ")!)
)//.navigationBarTitle(Text("Privacy Policy"))
) {
Text("Privacy Policy")
}
Text("Attribution")
}
}
.listStyle(GroupedListStyle())
.environment(\.horizontalSizeClass, .regular)
Solution 1:[1]
This is to be a bug in iOS. Please file a bug report to Apple.
I just discovered a workaround for this issue:
Create a custom subclass of UINavigationController
and use it as the navigation controller containing your MoreViewController
.
class WorkaroundUINavigationController: UINavigationController {
override var title: String? {
get { tabBarItem.title }
set { navigationItem.title = newValue }
}
}
Solution 2:[2]
Seems like @funkenstrahlen's workaround is aiming to solve the inverse of this problem and was resulting in a bad access exception in my case. For the case where the tabBarItem
's title is disappearing, this is a workaround that worked for me:
class WorkaroundUINavigationController: UINavigationController {
private var storedTabBarItem: UITabBarItem
override var tabBarItem: UITabBarItem! {
get { return storedTabBarItem }
set { storedTabBarItem = newValue }
}
}
You can set storedTabBarItem
in the init
or make it public and set it directly.
Solution 3:[3]
At start of application set YourTabBarController
to a singleton.
TabBarHelper.instance.tabBar = YourTabBarController()
Then something in like this in your SwifUIView .onAppear
VStack {}
.onAppear {
TabBarHelper.instance.removeTabBarItemsTitles()
}
Other classes may look like these
class TabBarHelper {
static let instance = TabBarHelper()
var tabBar: YourTabBarController?
func removeTabBarItemsTitles() {
tabBar.removeItemsTitles()
}
}
class YourTabBarController: UITabBarController {
...
func removeItemsTitles() {
tabBar.items.forEach { $0.title = nil }
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | funkenstrahlen |
Solution 2 | Jeremy Caney |
Solution 3 |