SwiftUI hide TabBar in subview

六月ゝ 毕业季﹏ 提交于 2020-07-18 04:35:06

问题


I am working with SwiftUI, and I have some issues with the TabBar. I want to hide the TabBar on a specific subview.

Have tried with

UITabBar.appearance().isHidden = true

It only works on the direct views in the TabView. But when I place it in a subview it doesn't work.

Have anyone a solution for this?

Thanks.


回答1:


here's no way to hide TabView so I had to add TabView inside ZStack as this:

var body: some View {
    ZStack {
        TabView {
            TabBar1().environmentObject(self.userData)
                .tabItem {
                    Image(systemName: "1.square.fill")
                    Text("First")
            }
            TabBar2()
                .tabItem {
                    Image(systemName: "2.square.fill")
                    Text("Second")
            }
        }

        if self.userData.showFullScreen {
            FullScreen().environmentObject(self.userData)

        }
    }
}

UserData:

  final class UserData: ObservableObject {
    @Published var showFullScreen = false
}

TabBar1:

struct TabBar1: View {
    @EnvironmentObject var userData: UserData

    var body: some View {
        Text("TabBar 1")
            .edgesIgnoringSafeArea(.all)
            .frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
            .background(Color.green)
            .onTapGesture {
                self.userData.showFullScreen.toggle()
        }
    }
}

FullScreen:

struct FullScreen: View {
    @EnvironmentObject var userData: UserData

    var body: some View {
        Text("FullScreen")
            .edgesIgnoringSafeArea(.all)
            .frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
            .background(Color.red)
            .onTapGesture {
                self.userData.showFullScreen.toggle()
        }
    }
}

check full code on Github

there's also some other ways but it depends on the structure of the views




回答2:


The basic idea I'm using is to combine ObservableObject and ZStack. I have placed TabView into ZStack with conditional subview presentation. It's look like. Look through github repo




回答3:


It is actually possible to get the underlying UITabbarController for TabView by using this handy little framework :

https://github.com/siteline/SwiftUI-Introspect

This solution uses the MVVM pattern as an example to have programmatic control over the Tabbar visibility, and be able to show, hide, enable, disable form anywhere in the code using NSNotifications

SwiftUI View : Setup the tabview like this

struct MainTabView: View {

var viewModel: MainTabViewModel

var body: some View {

    TabView() {

        Text("View1")
        .tabItem {
            Text("View1")
        }

        Text("View2")
        .tabItem {
            Text("View2")
        }

    }

    .introspectTabBarController { tabBarController in
        // customize here the UITabBarViewController if you like
        self.viewModel.tabBarController = tabBarController
    }

}
}

Then for the ViewModel

final class MainTabViewModel: ObservableObject {

var tabBarController: UITabBarController?

init() {
    startListeningNotifications()
}

func startListeningNotifications() {
    NotificationCenter.default.addObserver(self, selector: #selector(showTabbarView), name: "showBottomTabbar", object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(hideTabbarView), name: "hideBottomTabbar", object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(enableTabbarTouch), name: "enableTouchTabbar", object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(disableTabbarTouch), name: "disableTouchTabbar", object: nil)
}

@objc func showTabbarView() {
    self.tabBarController?.tabBar.isHidden = false
}

@objc func hideTabbarView() {
    self.tabBarController?.tabBar.isHidden = true
}

@objc func disableTabbarTouch() {
    self.tabBarController?.tabBar.isUserInteractionEnabled = false
}

@objc func enableTabbarTouch() {
    self.tabBarController?.tabBar.isUserInteractionEnabled = true
}

deinit {
    NotificationCenter.default.removeObserver(self)
}


}

and finally to control the tabbar, just use these fonctions from wherever you feel like (will be in the viewmodels in the pattern of this example)

public func showTabbar() {
    DispatchQueue.main.async {
        NotificationCenter.default.post(name: .showBottomTabbar, object: nil)
    }
}

public func hideTabbar() {
    DispatchQueue.main.async {
        NotificationCenter.default.post(name: .hideBottomTabbar, object: nil)
    }
}

public func enableTouchTabbar() {
    DispatchQueue.main.async {
        NotificationCenter.default.post(name: .enableTouchTabbar, object: nil)
    }
}

public func disableTouchTabbar() {
    DispatchQueue.main.async {
        NotificationCenter.default.post(name: .disableTouchTabbar, object: nil)
    }
}


来源:https://stackoverflow.com/questions/58444689/swiftui-hide-tabbar-in-subview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!