如何在没有NavigationView或Popover的情况下切换视图?

时间:2019-10-25 14:39:23

标签: swiftui

我正在尝试更改视图,而不会像在快速使用segue时那样覆盖视图。但是我想出的唯一解决方案是拥有导航栏navigationBar或弹出窗口。

struct view1: View {

    var body: some View{

        Button(action: {
//          go to view2``
        }) {
            Text("press")
        }

    }
}
struct view2: View {

    var body: some View{
       Text("yeay")

    }
}

3 个答案:

答案 0 :(得分:1)

如果您只想隐藏导航栏,那很容易:

import SwiftUI

struct View2: View {
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>

    var body: some View {
        VStack {
            Button(action: {
                self.presentationMode.wrappedValue.dismiss()
            }) {
                Text("POP")
            }
        }
        .navigationBarTitle("")
        .navigationBarBackButtonHidden(true)
        .navigationBarHidden(true)
    }
}

struct ContentView: View {
    var body: some View {
        NavigationView {
            NavigationLink(destination: View2()) {
                Text("PUSH")
                    .navigationBarTitle("")
                    .navigationBarHidden(true)
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

如果您想摆脱NavigationViewNavigationLink视图,则必须实现自己的自定义导航。有点复杂。以下只是两个视图之间的推/弹出过渡的简单示例。

import SwiftUI

struct View2: View {
    @Binding var push: Bool

    var body: some View {
        ZStack {
            Color.yellow
            Button(action: {
                withAnimation(.easeOut(duration: 0.3)) {
                    self.push.toggle()
                }
            }) {
                Text("POP")
            }
        }
        .edgesIgnoringSafeArea(.all)
    }
}

struct View1: View {
    @Binding var push: Bool

    var body: some View {
        ZStack {
            Color.green
            Button(action: {
                withAnimation(.easeOut(duration: 0.3)) {
                    self.push.toggle()
                }
            }) {
                Text("PUSH")
            }
        }
        .edgesIgnoringSafeArea(.all)
    }
}

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

    var body: some View {
        ZStack {
            if !push {
                View1(push: $push)
                    .transition(.asymmetric(insertion: .move(edge: .leading), removal: .move(edge: .leading)))
            }

            if push {
                View2(push: $push)
                    .transition(.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .trailing)))
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
  static var previews: some View {
    ContentView()
  }
} 

答案 1 :(得分:1)

您也可以在没有 NavigationView 的情况下完全做到这一点。看看下面的例子:

struct MainView: View
{
    @State private var showView = "LoginView"
    
    var body: some View
    {
        switch showView
        {
        case "LoginView":
            Text("Please login.")
            Button("Login")
            {
                showView = "NormalView"
            }
        case "NormalView":
            Text("This is youre NormalView!")
            Button("Next view")
            {
                showView = "NextView"
            }
        case "NextView":
            Text("This is the NextView")
            Button("Back")
            {
                showView = "NormalView"
            }
        default:
            Text("Default") // you should never reach this
        }
    }
}

也许不是最佳的代码实践,但它可以解决您的问题。

答案 2 :(得分:0)

以后来这里的任何人可能会发现这很有趣;简而言之,将一大堆数据推入@environment,在您想要的任何视图中按下按钮来刺激它,并且由于它位于整个应用程序堆栈的最顶部,因此它会强制重绘,这就像一个完整的视图导航,没有整个推送/弹出导航视图愚蠢的潜在丢失内存和孤立或丢失的对象。

它仍然比我想要的更像“单页应用程序”,但由于 SwiftUI 在导航完整性方面如此残缺,它会做得很好。

不是我的网站,不是我的链接,不是我的教程,搜索时它被埋在点击列表中,这是一种耻辱;这是最接近许多人正在寻找的。 IMO,这应该作为一流的操作融入 SwiftUI,并减少解决方法。

https://blckbirds.com/post/how-to-navigate-between-views-in-swiftui-by-using-an-environmentobject/