如何隐藏TabView中指定视图的<More返回按钮
隐藏TabView中More页面跳转后的返回按钮
问题描述
当TabView中的标签数量超过5个时,超出的标签会被系统收纳到「More」页面中。点击「More」里的标签(如示例中的Tab6)进入对应页面后,顶部会显示返回至「More」的按钮,直接在子视图上添加navigationBarBackButtonHidden(true)无法隐藏该按钮。
原始代码:
struct ExperimentView: View { var body: some View { TabView { AView(label: "1") .tabItem { Label("Tab1", systemImage: "list.dash") } AView(label: "2") .tabItem { Label("Tab2", systemImage: "square.and.pencil") } AView(label: "3") .tabItem { Label("Tab3", systemImage: "pencil.slash") } AView(label: "4") .tabItem { Label("Tab4", systemImage: "scribble") } AView(label: "5") .tabItem { Label("Tab5", systemImage: "pencil.tip") } AView(label: "6") .tabItem { Label("Tab6", systemImage: "pencil.and.outline") } } } } struct AView: View { var label: String var body: some View { VStack { Spacer() Text(label) Spacer() } } }
尝试过但无效的代码:
AView(label: "6") .navigationBarTitle("") .navigationBarBackButtonHidden(true) .tabItem { Label("Tab6", systemImage: "pencil.and.outline") }
解决方案
由于「More」页面的导航栈由系统管理,直接在SwiftUI视图上添加导航修饰符无法生效,需要通过UIKit的UITabBarController和UINavigationControllerDelegate来控制返回按钮的显示:
步骤1:创建自定义TabView包装器
struct CustomTabView: UIViewControllerRepresentable { var views: [AnyView] var tabItems: [UITabBarItem] func makeUIViewController(context: Context) -> UITabBarController { let tabBarController = UITabBarController() var viewControllers = [UIViewController]() // 将SwiftUI视图包装为UIHostingController for (index, view) in views.enumerated() { let hostingController = UIHostingController(rootView: view) hostingController.tabBarItem = tabItems[index] viewControllers.append(hostingController) } tabBarController.viewControllers = viewControllers // 设置初始返回按钮隐藏 tabBarController.moreNavigationController.navigationBar.topItem?.hidesBackButton = true // 监听导航栈变化,确保所有从More进入的页面都隐藏返回按钮 context.coordinator.navigationDelegate = tabBarController.moreNavigationController tabBarController.moreNavigationController.delegate = context.coordinator return tabBarController } func updateUIViewController(_ uiViewController: UITabBarController, context: Context) {} func makeCoordinator() -> Coordinator { Coordinator() } class Coordinator: NSObject, UINavigationControllerDelegate { func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) { // 隐藏即将显示的页面的返回按钮 viewController.navigationItem.hidesBackButton = true } } }
步骤2:替换原有TabView为自定义包装器
修改ExperimentView,用CustomTabView替代系统TabView:
struct ExperimentView: View { var body: some View { CustomTabView( views: [ AnyView(AView(label: "1")), AnyView(AView(label: "2")), AnyView(AView(label: "3")), AnyView(AView(label: "4")), AnyView(AView(label: "5")), AnyView(AView(label: "6")) ], tabItems: [ UITabBarItem(title: "Tab1", image: UIImage(systemName: "list.dash"), selectedImage: nil), UITabBarItem(title: "Tab2", image: UIImage(systemName: "square.and.pencil"), selectedImage: nil), UITabBarItem(title: "Tab3", image: UIImage(systemName: "pencil.slash"), selectedImage: nil), UITabBarItem(title: "Tab4", image: UIImage(systemName: "scribble"), selectedImage: nil), UITabBarItem(title: "Tab5", image: UIImage(systemName: "pencil.tip"), selectedImage: nil), UITabBarItem(title: "Tab6", image: UIImage(systemName: "pencil.and.outline"), selectedImage: nil) ] ) } }
原理说明
- 通过
UIViewControllerRepresentable将SwiftUI视图包装为UIKit的UITabBarController,从而获得对系统「More」导航栈的控制权。 - 实现
UINavigationControllerDelegate,在每次导航栈跳转时,强制隐藏目标页面的返回按钮,确保从「More」进入的所有页面都不会显示返回按钮。
内容的提问来源于stack exchange,提问作者Fab
相关产品推荐
相关产品推荐

