UITabBar containing SwiftUI View
Asked Answered
E

4

7

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)
Emeliaemelin answered 30/6, 2020 at 16:47 Comment(3)
I have exactly the same problem!Camey
@Camey Im not having the issue in Xcode 12 beta 2 is should be fixed by fall at the latestEmeliaemelin
@AustinE it's back in the final version :(Aho
C
6

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 }
    }
}
Camey answered 5/7, 2020 at 8:52 Comment(1)
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.Erhart
G
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.

Gunk answered 19/4, 2022 at 18:47 Comment(1)
This worked for me. Thank you! What an annoying bug to run into on a Friday afternoon.Altimeter
P
2

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 }
    }
}
Penitential answered 8/2, 2023 at 21:10 Comment(0)
D
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 }
  }
}
Discard answered 26/4, 2022 at 14:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.