SwiftUI NavigationLink:成功运行帐户创建代码后导航到目标视图

Joe*_*ney 13 swiftui

我想运行帐户创建逻辑,然后,如果成功,转换到目标视图。否则,我将提供错误表。NavigationLink 会立即转换到目标视图。

如果我使用 isActive 重载和空字符串作为文本(它创建一个具有零帧的视图)创建一个幻影 NavigationLink,我可以让它工作。然后,我使用显示给用户的按钮切换 isActive 属性,该按钮首先运行帐户创建逻辑,并在链的末尾将 NavigationLink 切换为活动状态。我在一个 NavigationView 里面。

        @State private var isActive: Bool = false

        NavigationView {

            // Name, Email, Password Textfields here

            // Button to run account creation logic:

            Button(action: {
                // Account creation promise chain here, then...
                self.isActive.toggle()
            }) {
                Text("Create Account")
            }

            // Phantom navigation link:

            NavigationLink("", destination: VerifyEmailView(email: email), isActive: self.$isActive)

        }
Run Code Online (Sandbox Code Playgroud)

有一个更好的方法吗?从按钮触发运行帐户创建逻辑,然后激活虚拟导航链接以转换到下一个屏幕似乎是不好的做法。

moh*_*wal 13

有一种非常简单的方法来处理您的视图状态和NavigationLinks. 您可以NavigationLink通过将 a 绑定tag到它来通知您自己执行。然后,您可以设置-取消设置标签并控制您的NavigationLink.

struct SwiftView: View {
@State private var actionState: Int? = 0

var body: some View {

    NavigationView {
                VStack {
                    NavigationLink(destination: Text("Destination View"), tag: 1, selection: $actionState) {
                        EmptyView()
                    }


                    Text("Create Account")
                        .onTapGesture {
                            self.asyncTask()
                    }
                }
            }
    }

func asyncTask() {
    //some task which on completion will set the value of actionState
    self.actionState = 1
}
Run Code Online (Sandbox Code Playgroud)

}

在这里,我们将 theactionState与 our绑定NavigationLink,因此每当值发生actionState变化时,它将tag与与 our 关联的进行比较NavigationLink

你的目标视图,直到你的值设置将不可见actionState等于tag与我们相关NavigationLink

像这样,您可以创建任意数量的NavigationLinks并可以通过更改一个Bindable属性来控制它们。

谢谢,希望这有帮助。


Zac*_*iro 8

基于 Mohit 的答案,使用封装屏幕状态的枚举使 Swifty 更加简洁:


enum ActionState: Int {
    case setup = 0
    case readyForPush = 1
}

struct SwiftView: View {
    @State private var actionState: ActionState? = .setup

    var body: some View {

        NavigationView {
                VStack {
                    NavigationLink(destination: SomeView, tag: .readyForPush, selection: $actionState) {
                        EmptyView()
                    }


                    Text("Create Account")
                        .onTapGesture {
                            self.asyncTask()
                    }
                }
            }
       }

func asyncTask() {
    //some task which on completion will set the value of actionState
    self.actionState = .readyForPush
}
Run Code Online (Sandbox Code Playgroud)