SwiftUI NavigationLink: Navigate to a destination view AFTER running account creation code successfully

后端 未结 3 1795
渐次进展
渐次进展 2021-01-04 17:30

I want to run account creation logic and then, if successful, transition to the destination view. Otherwise, I\'ll present an error sheet. NavigationLink transitions immedia

相关标签:
3条回答
  • 2021-01-04 17:40

    You can wrap your Destination View in a lazy view to prevent the immediate invocation. Here's an example:

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

    Eventually, invoke it like this:

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

    I've written a full blog post covering this a few other pitfalls of NavigationLinks in SwiftUI. Refer here.

    0 讨论(0)
  • 2021-01-04 17:47

    Building off of Mohit's answer, making a little more Swifty with an enum that encapsulates screen state:

    
    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
    }
    
    0 讨论(0)
  • 2021-01-04 17:53

    There is a very simple approach to handle your views' states and NavigationLinks. You can notify your NavigationLink to execute itself by binding a tag to it. You can then set-unset the tag and take control of your 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
    }
    

    }

    Here we have binded the actionState with our NavigationLink, hence whenever the value of actionState changes, it will be compared with the tag associated with our NavigationLink.

    Your Destination View will not be visible until you set the value of actionState equal to the tag associated with our NavigationLink.

    Like this you can create any number of NavigationLinks and can control them by changing just one Bindable property.

    Thanks, hope this helps.

    0 讨论(0)
提交回复
热议问题