从按钮显示新视图并按Swift UI

时间:2019-07-10 08:41:13

标签: swiftui

当我在其中一个视图上按下按钮时,我希望能够显示一个新视图。

从我看过的教程以及此处的其他回答的问题来看,似乎每个人都在导航视图中使用导航按钮,除非错误的导航视图是使我在应用顶部显示菜单栏右箭头的菜单我不要当我将导航按钮放入不是NavigationView的子视图时,它只是在UI上被禁用,因此我无法单击它,所以我想我不能使用它。

我看到的其他示例似乎使用了演示文稿链接/按钮,它们似乎显示了一种弹出视图。

我只是在寻找如何单击常规按钮并以全屏方式显示另一个视图,就像执行旧的处理方式一样。

2 个答案:

答案 0 :(得分:4)

可能的解决方案

1。如果要在当前视图的顶部显示(例如,UIKit中的显示样式)

struct ContentView: View {
    @State var showingDetail = false

    var body: some View {
        Button(action: {
            self.showingDetail.toggle()
        }) {
            Text("Show Detail")
        }.sheet(isPresented: $showingDetail) {
            DetailView()
        }
    }
}

2。如果要重置当前窗口场景堆栈(例如:登录后显示主屏幕)

Button(action: goHome) {
    HStack(alignment: .center) {
        Spacer()
        Text("Login").foregroundColor(Color.white).bold()
        Spacer()
    }
}

func goHome() {
    if let window = UIApplication.shared.windows.first {
        window.rootViewController = UIHostingController(rootView: HomeScreen())
        window.makeKeyAndVisible()
    }
}

3.push新视图(例如:list-> UIKit导航控制器的详细信息)

struct ContentView: View {
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: DetailView()) {
                    Text("Show Detail View")
                }.navigationBarTitle("Navigation")
            }
        }
    }
}

4。基于@state属性更新当前视图,(例如:登录失败时显示错误消息)

    struct ContentView: View {
        @State var error = true
        var body: some View {
            ...
            ... //login email
            .. //login password
            if error {
                Text("Failed to login")
            }
        }
    }

答案 1 :(得分:1)

举个简单的例子,您可以使用以下内容

import SwiftUI

struct ExampleFlag : View {
    @State var flag = true
    var body: some View {
        ZStack {
            if flag {
                ExampleView().tapAction {
                    self.flag.toggle()
                }
            } else {
                OtherExampleView().tapAction {
                    self.flag.toggle()
                }
            }
        }
    }
}
struct ExampleView: View {
     var body: some View {
        Text("some text")
    }
}
struct OtherExampleView: View {
    var body: some View {
        Text("other text")
    }
}

但是如果您想以这种方式显示更多视图,则看起来很讨厌

您可以使用堆栈来控制视图状态,而无需使用NavigationView

例如:

    class NavigationStack: BindableObject {
        let didChange = PassthroughSubject<Void, Never>()

        var list: [AuthState] = []

        public func push(state: AuthState) {
            list.append(state)
            didChange.send()
        }
        public func pop() {
            list.removeLast()
            didChange.send()
        }
    }

    enum AuthState {
        case mainScreenState
        case userNameScreen
        case logginScreen
        case emailScreen
        case passwordScreen
    }
    struct NavigationRoot : View {
        @EnvironmentObject var state: NavigationStack
        @State private var aligment = Alignment.leading

        fileprivate func CurrentView() -> some View {
            switch state.list.last {
            case .mainScreenState:
                return AnyView(GalleryState())
            case .none:
                return AnyView(LoginScreen().environmentObject(state))
            default:
                return AnyView(AuthenticationView().environmentObject(state))
            }
        }
        var body: some View {
        GeometryReader { geometry in
            self.CurrentView()
                .background(Image("background")
                    .animation(.fluidSpring())
                    .edgesIgnoringSafeArea(.all)
                    .frame(width: geometry.size.width, height: geometry.size.height,
                           alignment: self.aligment))
                    .edgesIgnoringSafeArea(.all)
                    .onAppear {
                        withAnimation() {
                            switch self.state.list.last {
                            case .none:
                                    self.aligment = Alignment.leading
                            case .passwordScreen:
                                    self.aligment = Alignment.trailing
                            default:
                                    self.aligment = Alignment.center
                            }
                        }
                    }
                }
            .background(Color.black)
        }

}

struct ExampleOfAddingNewView: View {
    @EnvironmentObject var state: NavigationStack
    var body: some View {
            VStack {
                Button(action:{ self.state.push(state: .emailScreen) }){
                Text("Tap me")
            }

        }
    }
}


    struct ExampleOfRemovingView: View {
        @EnvironmentObject var state: NavigationStack
        var body: some View {
            VStack {
                Button(action:{ self.state.pop() }){
                    Text("Tap me")
                }
            }
        }
    }

我认为这是一种糟糕的方式,但是SwiftUI中的导航要糟糕得多