在导航上隐藏TabBar

问题描述

我创建了一个TabBar,它是应用程序根目录下的一个视图。 从壁橱视图导航到子视图时,我想隐藏TabBar组件。 壁橱视图是一个包含多个NavigationLink的NavigationView

这是应用程序的根视图:

struct Home: View {
@State var selected = 0
@Observedobject var viewmodel: Homeviewmodel

init(viewmodel: Homeviewmodel) {
    self.viewmodel = viewmodel
}

var body: some View {
    ZStack {
        
        if self.selected == 0 {
            // viewmodel.FeedView
            Stylist()
        }
        else if self.selected == 1 {
            OutfitView()
        }
        else if self.selected == 2 {
            viewmodel.closetView
        } else {
            Calendar()
        }
        
        vstack {
            Spacer()
            TabBar(selected: self.$selected)
                .frame(width: UIScreen.main.bounds.width - 20,alignment: .center)
        }
    }
}

这是TabBar组件:

var body : some View{
    HStack{
        Spacer(minLength: 0)
        
        HStack{
            Button(action: {
                
                self.selected = 0
                
            }) {
                
                Image(systemName: "bolt.fill").foregroundColor(self.selected == 0 ? Color("GradientMiddle") : .gray).padding(.horizontal).font(.system(size: 20))
            }
            
            Spacer(minLength: 15)
            
            Button(action: {
                
                self.selected = 1
                
            }) {
                
                Image(systemName: "sun.min.fill").foregroundColor(self.selected == 1 ? Color("GradientMiddle") : .gray).padding(.horizontal).font(.system(size: 20))
            }
            
            Spacer(minLength: 15)
            
            Button(action: {
                
                self.selected = 2
                
            }) {
                
                Image(systemName: "cube.Box.fill").foregroundColor(self.selected == 2 ? Color("GradientMiddle") : .gray).padding(.horizontal).font(.system(size: 20))
            }
            
            Spacer(minLength: 15)
            
            Button(action: {
                
                self.selected = 4
                
            }) {
                
                Image(systemName: "calendar").foregroundColor(self.selected == 4 ? Color("GradientMiddle") : .gray).padding(.horizontal).font(.system(size: 20))
            }
        }.padding(.vertical,20)
            .padding(.horizontal)
            .background(Color(UIColor.systemGray5))
            .clipShape(Capsule())
            .padding(42)
            .animation(.interactiveSpring(response: 0.6,dampingFraction: 0.6,blendDuration: 0.6))
    }
    
    
}

有没有办法解决这个问题?

更新: 当我尝试@Asperi解决方案时出现错误

Value of type 'some View' has no member 'observingNavigate'

也许这是由于我如何创建closetView引起的? 所以这是我创建ClosetView的方法: Homeviewmodel.swift:

class Homeviewmodel: ObservableObject {
} 
extension Homeviewmodel { 
    var closetView: some View { 
        return HomeBuilder.makeClosetView() 
    }
}

HomeBuilder.swift:

enum HomeBuilder {
    static func makeClosetView() -> some View { 
        let viewmodel = Closetviewmodel()
        return Closet(viewmodel: viewmodel) 
    } 
}

解决方法

您需要在壁橱视图中进行回调,以便根视图可以执行某些操作。这是可能解决方案的演示。

假设我们有以下示例ClosetView

struct ClosetView: View {
    var didNavigate: ((Bool) -> Void)?

    var body: some View {
        NavigationView {
            NavigationLink("Link",destination:
                Text("Demo")
                    .onAppear { didNavigate?(true) }
                    .onDisappear { didNavigate?(false) }
            )
        }
    }

    func observingNavigate(callback: @escaping ((Bool) -> Void)) -> some View {
        var view = self
        view.didNavigate = callback
        return view
    }
}

然后Home中的更改如下

@State private var showTabbar = true    // << state !!

var body: some View {
    ZStack {
        
        if self.selected == 0 {
            // viewModel.feedView
            Stylist()
        }
        else if self.selected == 1 {
            OutfitView()
        }
        else if self.selected == 2 {
            viewModel.closetView
              .observingNavigate { self.showTabbar = !$0 }   // << here !!
        } else {
            Calendar()
        }
        
        VStack {
            Spacer()
            if showTabbar {                      // << here !!
              TabBar(selected: self.$selected)
                .frame(width: UIScreen.main.bounds.width - 20,alignment: .center)
            }
        }
    }
}

注意:我看不到如何创建viewModel.closetView,因此回调作为属性被注入,但是也可以通过构造函数参数来注入,但这并没有太大改变。