仅在第一页上隐藏导航栏-Swift UI

时间:2019-10-16 13:30:53

标签: swiftui ios13

我的应用程序在Swift UI上运行,我的主页是Home(),主页中有NavigationView和NavigationLink(destination:SaveThePlanet()),我在主页“ Home”上隐藏了Navigation View,它也隐藏在SaveThePlanet()中。 如何取消隐藏SaveThePlanet()页面中的导航后退按钮?

import SwiftUI

struct Home: View {

    @State var show = false
    @State var showSaveThePlanet = false
    var body: some View {
        NavigationView {
            ZStack {
                Color.gray
                ContentView()
                    .blur(radius: show ? 10 : 0)
                    .scaleEffect(show ? 0.90 : 1)
                    .blur(radius: showSaveThePlanet ? 10 : 0)
                    .scaleEffect(showSaveThePlanet ? 0.90 : 1)
                    .animation(.default)

                leftIcon(show: $show)
                    .offset(x: 0, y: showSaveThePlanet ? 300 : 70)
                    .scaleEffect(show ? 0.90 : 1)
                    .blur(radius: show ? 10 : 0)
                    .animation(.easeInOut)

                SaveThePlanet()
                    .background(Color("Bg"))
                    .cornerRadius(10)
                    .shadow(color: Color("Green-Sh"), radius: 10, x: 0, y: 0)
                    .animation(.spring())
                    .offset(y: showSaveThePlanet ? 120 : UIScreen.main.bounds.height)
                    .padding()

                rightIcon(show: $showSaveThePlanet)
                    .offset(x: 0, y: 70)
                    .animation(.easeInOut)
                    .scaleEffect(show ? 0.90 : 1)
                    .blur(radius: show ? 10 : 0)
                    .opacity(showSaveThePlanet ? 0 : 1)


                rightIconClose(show: $showSaveThePlanet)
                    .offset(x: 0, y: 70)
                    .animation(.easeInOut)
                    .scaleEffect(show ? 0.90 : 1)
                    .blur(radius: show ? 10 : 0)
                    .opacity(showSaveThePlanet ? 1 : 0)

                MenuView(show: $show)
            }
            .edgesIgnoringSafeArea(.all)
            .navigationBarTitle("Home")
            .navigationBarHidden(true)
            .navigationBarBackButtonHidden(false)

        }
    }
}

3 个答案:

答案 0 :(得分:5)

对我有用的方法:第一个视图上有一个@State属性,该属性确定是否可以显示导航栏。然后通过@Binding将该属性传递给所有后续视图,以使它成为导航栏是否应显示的“唯一事实来源”。

@State private var navBarHidden = false

然后在主视图上,为navBarHidden属性引用该属性,然后设置标题。还添加一个onAppear闭包,它将为该视图重新出现时(即,如果我们从详细视图中弹出)重新设置该隐藏属性。

var body: some View {
    NavigationView {
        NavigationLink(
            destination: DetailView(navBarHidden: self.$navBarHidden)
        ) {
            Text("Go to detail view")
        }
    }
    .navigationBarTitle("")
    .navigationBarHidden(self.navBarHidden)
    .onAppear(perform: {
        self.navBarHidden = true
    })
}

然后在随后的详细信息视图中,将该navBarHidden属性作为@Binding传递(在上面传递)

@Binding var navBarHidden : Bool

var body: some View {
    Text("Hello Detail View!")
        .navigationBarTitle("Detail")
        .onAppear() {
            self.navBarHidden = false
        }

}

当在详细视图中在上方调用onAppear()时,会将原始属性设置为false以隐藏,这将显示导航栏。当您单击返回到主视图时,将再次调用主视图的onAppear(),这会将其设置回hidden = true。

答案 1 :(得分:0)

根据您发布的代码很难区分,但是看起来您正在尝试呈现showSaveThePlanet为true时从底部向上滑动的视图,并显示导航栏仅当该视图出现时。

这可以通过在您的.navigationBarHidden(!showSaveThePlanet)属性中的任意位置设置body来完成。请注意,您的代码没有在任何地方使用NavigationLink来将新视图推送到NavigationView堆栈中,因此您不会获得后退按钮。您可以使用.navigationBarItems(leading:)

添加自己的按钮以关闭工作表

这是一个简化的示例,显示了我的意思。

struct ContentView: View {
    @State private var detailShowing = false

    var body: some View {
        NavigationView {
            ZStack(alignment: Alignment(horizontal: .center, vertical: .top)) {
                Color.gray.edgesIgnoringSafeArea(.all)

                // A card-like view that is initially offscreen,
                // and slides on when detailShowing == true
                DetailView()
                    .offset(x: 0, y: detailShowing ? 120 : UIScreen.main.bounds.height)
                    .animation(.spring())

                // Just here to change state
                Button("Toggle") {
                        self.detailShowing.toggle()
                }
                .padding()
                .offset(x: 0, y: detailShowing ? 0 : 44)
                .animation(.none)
            }
            // This is the key modifier
            .navigationBarHidden(!detailShowing)
            .navigationBarTitle("Detail View", displayMode: .inline)
            .navigationBarItems(leading: Button("Close") {
                self.detailShowing = false
            })
        }
    }
}

struct DetailView: View {
    var body: some View {
        ZStack(alignment: Alignment(horizontal: .center, vertical: .top)) {
            RoundedRectangle(cornerRadius: 15).fill(Color.secondary).frame(width: 300, height: 500)
            Text("Detail Content")
                .padding()
        }
    }
}

答案 2 :(得分:0)

我发现的最佳方法是在目标视图中切换navBarHidden。这种不完整的滑动弹出手势不会删除导航栏。

所以在主视图中,您应该写

@State private var navBarHidden = true

var body: some View {
NavigationView {
    NavigationLink(
        destination: DetailView(navBarHidden: self.$navBarHidden)
    ) {
        Text("Go to detail view")
    }
}
.navigationBarTitle("")
.navigationBarHidden(self.navBarHidden)
}

在目标视图中:

@Binding var navBarHidden : Bool
var body: some View {
Text("Hello Detail View!")
    .navigationBarTitle("Detail")
    .onAppear {
        self.navBarHidden = false
    }
    .onDisappear {
        self.navBarHidden = true
    }
}