SwiftUI - TabView的基本使用,及TabView如何隐藏TabBar

SwiftUI - TabView

TabView是对UITabBarController的封装。本章包含TabView的基本使用,及TabView如何隐藏TabBar。

一、基本使用

要创建带有选项卡的用户界面,请将View放在TabView中,并对每个选项卡的内容应用tabItem(_:)修饰符。下面创建了一个有2个选项卡的TabView:

struct ContentView: View {
    @State private var selection = 1
    
    var body: some View {
        TabView(selection: $selection){
            FirstTab()
                .tabItem {
                    VStack {
                        Image("first")
                        Text("FirstTab")
                    }
                }
                .tag(0)
            SecondTab()
                .tabItem {
                    VStack {
                        Image("second")
                        Text("SecondTab")
                    }
                }
                .tag(1)
        }
    }
}
  1. TabView只支持Text、Image或Image后跟Text的选项卡项。传递任何其他类型的视图都会导致一个可见但空的选项卡项;
  2. selection属性指示默认哪个tag选项卡选中;

二、隐藏TabBar

我们知道从TabView导航到下一个页面时需要隐藏TabBar,但是TabView没有的属性直接提供隐藏TabBar的功能。解决思路:TabView底层的实现是UITabBarController,如果我们获取到UITabBarController就能够隐藏TabBar了,这里需要使用到ObservableObject和EnvironmentObject。

  1. 定义TabBarState
 // TabBarState.swift
 class TabBarState: ObservableObject {
    @Published var hidden : Bool = false
}
  1. 创建TabBarState对象,并将TabBarState对象通过EnvironmentObject传递给TabView及其子View。监听TabBarState.hidden属性,并设置TabBar.isHidden。
 // SceneDelegate.swift
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
        // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
        // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).

        // Create the SwiftUI view that provides the window contents.
        let contentView = ContentView()
        // Use a UIHostingController as window root view controller.
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            let tabBar = TabBarState()
            window.rootViewController = UIHostingController(rootView: contentView.environmentObject(tabBar))
            self.window = window
            window.makeKeyAndVisible()
            
            //监听TabBarState状态
            tabBar.$hidden.receive(subscriber: AnySubscriber(receiveSubscription: { (sub) in
                sub.request(.unlimited)
            }, receiveValue: { (value) -> Subscribers.Demand in
                self.tabBarHidden(hidden: value)
                return .none
            }))
        }
    }

    func tabBarHidden(hidden:Bool){
        for viewController in self.window!.rootViewController!.children {
            if viewController.isKind(of: UITabBarController.self) {
                let tabBarController = viewController as! UITabBarController
                if tabBarController.tabBar.isHidden != hidden {
                    tabBarController.tabBar.isHidden = hidden
                }
                return
            }
        }
    }
 // ContentView.swift
 struct ContentView: View {
    @State private var selection = 1
    @EnvironmentObject var tabBar : TabBarState
    
    var body: some View {
        TabView(selection: $selection){
            FirstTab()
                .environmentObject(tabBar)
                .tabItem {
                    VStack {
                        Image("first")
                        Text("FirstTab")
                    }
                }
                .tag(1)
            SecondTab()
                .environmentObject(tabBar)
                .tabItem {
                    VStack {
                        Image("second")
                        Text("SecondTab")
                    }
                }
                .tag(2)
        }
    }
}
  1. TabView子View通过TabBarState设置hidden属性控制TabBar的显示隐藏
// FirstTab.swift
struct FirstTab : View {
   @EnvironmentObject var tabBar : TabBarState
   var body: some View {
       List{
           NavigationLink(destination: FirstDetailView().environmentObject(tabBar)){
               Text("第1行")
           }
           NavigationLink(destination: SecondDetailView()
   							            .onAppear{
   									         self.tabBar.hidden = true
   									    }
   	       ){
               Text("第2行")
           }
       }
       .onAppear{
           self.tabBar.hidden = false
       }
   }
}
// FirstDetailView.swift
struct FirstDetailView : View {
   @EnvironmentObject var tabBar : TabBarState
   var body: some View {
       Text("我是FirstDetailView")
       .onAppear{
           self.tabBar.hidden = true
       }
   }
}

FirstDetailView和SecondDetailView两种实现方式都可以。这里用到了View的生命周期onAppear。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值