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

时间:2019-08-28 18:00:53

标签: 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)

        }

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

3 个答案:

答案 0 :(得分:5)

以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
}

答案 1 :(得分:3)

有一种非常简单的方法来处理视图的状态和NavigationLinks。 您可以通过将NavigationLink绑定到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
}

}

在这里,我们已经将actionState与我们的NavigationLink绑定在一起,因此只要actionState的值发生变化,它就会与与我们的{{1 }}。

您的目标视图将不可见,直到您将tag的值设置为等于与我们的NavigationLink关联的actionState为止。

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

谢谢,希望能对您有所帮助。

答案 2 :(得分:1)

您可以将目标视图包装在惰性视图中,以防止立即调用。这是一个示例:

struct LazyView<Content: View>: View {
    let build: () -> Content
    init(_ build: @autoclosure @escaping () -> Content) {
        self.build = build
    }
    var body: Content {
        build()
    }
}

最终,像这样调用它:

NavigationLink(destination: LazyView(Text("Detail Screen"))){//your code}

我写了一篇完整的博客文章,介绍了SwiftUI中NavigationLinks的其他一些陷阱。 Refer here.