摆脱tabview内的导航栏

时间:2019-11-11 14:36:10

标签: swift swiftui

我有这个实现:

View_1:包含一个navigationView和2个按钮,如下所示

NavigationView {
                GeometryReader { gr in
                ZStack {
                    VStack(alignment: HorizontalAlignment.center, spacing: 10) {
                        HStack{
                            Spacer()
                        }
                        Text("1").foregroundColor(.white).padding(EdgeInsets(top: 30, leading: 0, bottom: 0, trailing: 0))
                        Text("2").foregroundColor(.white)
                        Spacer()
                        HStack {
                            NavigationLink(destination: SigninScreen()){
                                Text("Button 1")
                            }

                            Button(action: {}){
                                Text("Button 2")
                            }
                        }.padding()
                    }.background(Image("bg-welcome")
                        .resizable()
                        .aspectRatio(contentMode: .fill)).edgesIgnoringSafeArea(.all)
                }.navigationBarHidden(true)
            }

然后显示目标屏幕(SigninScreen):

struct SigninScreen: View {
    @State private var email: String = ""
    @State private var password: String = ""
    var body: some View {
        VStack {
            Spacer()
            HStack {
                Spacer()
            }
            Text("SigninScreen")
            VStack {
                TextField("Email", text: self.$email)
                .padding()
                    .background(Color.white)
                    .overlay(RoundedRectangle(cornerRadius: 1).stroke(Color.white, lineWidth: 2))

                SecureField("Password", text: self.$password)
                    .padding()
                    .background(Color.white)
                .overlay(RoundedRectangle(cornerRadius: 1).stroke(Color.white, lineWidth: 2))

                Button(action: {}){
                    NavigationLink(destination: MainScreen()){
                        Text("Sign in").foregroundColor(.white)
                    }


                    .padding(EdgeInsets(top: 10, leading: 40, bottom: 10, trailing: 40))
                        .border(Color.white)

                }
            }.padding()

            Spacer()
            }.background(Color.red).edgesIgnoringSafeArea(Edge.Set.all).navigationBarHidden(true)

    }
}

struct SigninScreen_Previews: PreviewProvider {
    static var previews: some View {
        SigninScreen()
    }
}

最后是最后一个视图:

struct MainScreen: View {
    var body: some View {
        TabView(){
            HomeScreen()
                .tabItem {
                    Image(systemName: "house")
                    Text("Home")
            }
            EventsScreen()
                .tabItem {
                    Image(systemName: "calendar")
                    Text("Events")
            }
            NewsScreen()
                .tabItem {
                    Image(systemName: "info")
                    Text("News")
            }

        }
    }
}

struct MainScreen_Previews: PreviewProvider {
    static var previews: some View {
        MainScreen()
    }
}

homeview的实现方式如下

struct HomeScreen: View {
    var body: some View {
        VStack {
            HStack{
                Spacer()
            }
            Text("cacaca")
            Spacer()
        }.background(Color.yellow).padding(EdgeInsets(top: -150, leading: 0, bottom: 0, trailing: 0))

    }
}

struct HomeScreen_Previews: PreviewProvider {
    static var previews: some View {
        HomeScreen()
    }
}

我的问题是导航栏在视图顶部占用了我想使用的空间 而且,例如,如果不添加新的Navigationview,就无法将标题附加到homeview。在我要显示的内容之前,这会在顶部添加更多空间。

关于如何解决此问题的任何想法?

enter image description here

2 个答案:

答案 0 :(得分:0)

听起来好像您正在使用NavigationView在视图之间进行切换,但实际上您并不需要NavigationView的功能(顶部的标题,后退按钮,后退按钮等) )

因此,我建议您不要具有三个未堆叠的视图:NavigationViewWelcomeScreenSigninScreen,而不是使主视图深入MainScreen中的两个层次。然后,您的内容视图应根据您应用的状态在这些视图之间显示/转换。

如何在它们之间进行转换有很多可能性(使视图的不透明性淡入和淡出,使视图在屏幕中滑入和滑出,等等。)有关图片的完整示例,请参见this answer ,但看起来可能像这样:

class LoginStateModel: ObservableObject {
    enum CurrentView {
        case welcome, login, home
    }

    @Published var currentView = CurrentView.login
}

struct StackOverflowTests: View {
    @ObservedObject var model = LoginStateModel()

    var body: some View {
        ZStack {
            if model.currentView == .welcome {
                WelcomeScreen()
            } else if model.currentView == .login {
                SigninScreen()
            } else {
                MainScreen()
            }
        }
        .environmentObject(model)
    }
}

该模型通过.environmentObject传递给子视图,以便他们可以对其进行修改(例如,SigninScreen在成功登录时将模型设置为.homeMainScreen设置模型到.login退出)。


作为附录,您实际上可以为MainScreen设置新标题,只需在其.navigationBarTitle属性(例如body)的某个地方添加另一个TabView修饰符即可。但如上所述,我仍然建议您摆脱NavigationView

答案 1 :(得分:0)

使用此扩展程序隐藏导航栏

extension View {
  func hideNavigationBar() -> some View {
        self
          .navigationBarTitle(Text(""))
          .navigationBarHidden(true)
    }
}