简体   繁体   中英

Change view on completion in SwiftUI

I have developed a view that manages three subviews: login , register and confirm code .

Now I'm developing a separate view that manages all the subviews after login successful. The idea is that after login with success the new is pushed and the old is popped.

I've tried with NavigationLink in the login subview but it seems that it doesn't like the isActive change in the rest response (ie in the completion).

Here is the code:

NavigationLink(
   destination: LoggedView(),
   isActive: self.$pushToLogged,
   label: {
                
   }
).hidden()
func login() {
    let lF = LoginServiceFacade()
    lF.loginMember(mobileNumber: mobileNumber, password: password, completion: {
        (response: LoginResponse?, error: ConnectionErrors?) in
            self.pushToLogged = true
    })
}

This is quite a simple and understandable example of a possible way of doing so:

First provide a wrapping view that checks if you are logged in or not. Display the according view:

struct ContentView: View {
    
    @State var isLoggedIn: Bool = false
    
    var body: some View {
        Group() {
            if self.isLoggedIn {
                Home(isLoggedIn: self.$isLoggedIn)
            } else {
                Login(isLoggedIn: self.$isLoggedIn)
            }
        }
    }
}

Then have your home view which can have whatever structure you want. I for eg choose a TabView:

struct Home: View {
    
    @Binding var isLoggedIn: Bool
    
    var body: some View {
        TabView {
            Example(subTitle: "First")
                .tabItem {
                    Image(systemName: "list.dash")
                    Text("First")
                }

            Example(subTitle: "Second")
                .tabItem {
                    Image(systemName: "square.and.pencil")
                    Text("Second")
                }
        }
    }
}

struct Example: View {
    
    @State var subTitle: String
    
    var body: some View {
        Text("Hello World \(self.subTitle)")
    }
}

The login view with the completion:

struct Login: View {
    
    @Binding var isLoggedIn: Bool
    
    var myLogin: myLoginClass = myLoginClass()
    
    var body: some View {
        Button(action: {
            self.myLogin.loginWithCompletion { isSucceeded in
                if isSucceeded {
                    self.isLoggedIn.toggle()
                }
            }
        }) {
            Text("Log me in")
        }
    }
}

class myLoginClass {
    // Completing method
    // Here would be your code that would "complete" true if successfully logged in or false if error

    // I'm just waiting to "simulate" the visual process
    func loginWithCompletion(completion: @escaping (Bool) -> Void) {
        DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
            completion(true)
        }
    }
    
}

This produces this example:

示例为 gif

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM