'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