5

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)
Austin E
  • 823
  • 1
  • 9
  • 22

4 Answers4

5

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 }
    }
}
funkenstrahlen
  • 3,032
  • 2
  • 28
  • 40
  • 2
    I have this same situation with a custom MoreViewController. This solution seems to cause a loop between the getter and setter no matter what I do. – Brandt Nov 10 '20 at 00:25
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.

Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77
taeyawn
  • 21
  • 1
0

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 }
  }
}
hariszaman
  • 8,202
  • 2
  • 40
  • 59
0

I used the following code (very similar @taeyawn's version) that fixed the problem with disappearing tab bar title for me and didn't need setting storedTabBarItem in init:

class WorkaroundUINavigationController: UINavigationController {
    private var storedTabBarItem: UITabBarItem?
    override var tabBarItem: UITabBarItem! {
        get { return storedTabBarItem ?? super.tabBarItem }
        set { storedTabBarItem = newValue }
    }
}
Marián Černý
  • 15,096
  • 4
  • 70
  • 83