0

I have a login view that does an http request . Once we get the http response we know whether the user can go to the next view . I am wondering how can I trigger the next view without click ? I am not looking to do a sheet since I want to get the full screen mode . I have been looking at this Go to a new view using SwiftUI but no luck . From my code below when I click on Press on me navigationLink I can go to the correct view, however I need that same functionality to work without clicking in the http response below where it says decode.status == 1 because the user has authenticated successfully .

struct ContentView: View {
    @State var email: String = ""
    @State var password: String = ""
    @State var message: String = ""
    @State var status: Int = -10
    @State var showActive = true
 
    var body: some View {

        NavigationView {
        ZStack {
            
           Color(UIColor.systemGroupedBackground)
            .edgesIgnoringSafeArea(.all)
            
           
        VStack(alignment: .center) {
      
            Spacer()
            
            NavigationLink(destination: MainView()) {
               Text("Press on me")
            }.buttonStyle(PlainButtonStyle()) // This works when clicked
            
            TextField("Email", text: $email)
                .padding(10)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .background(Color(UIColor(hexString: ForestGreen)))
                .foregroundColor(Color.black)
            
            SecureField("Password", text: $password)
                .padding(10)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .background(Color(UIColor(hexString: ForestGreen)))
                .foregroundColor(Color.black)

             
            Button(action: {
                guard  let url = URL(string:ConnectionString+"profile/login") else { return }
                let parameter = "email=\(self.email)&password=\(self.password)"
                let request = RequestObject(AddToken: true, Url: url, Parameter: parameter)
                
                URLSession.shared.dataTask(with:request, completionHandler: {(data, response, error) in
                    if let decode = try? JSONDecoder().decode(ProfileCodable.self, from: data!)
                    {
                        self.status = decode.status ?? -10
                        self.message = decode.message ?? ""
                        if decode.status == 0 {
                            print("Invalid Credentials")
                        } else if decode.status == 1 {
                
                           // ** Go to next View here **
                            
                        } else if decode.status == -1 {
                            print("Error")
                        }
                        
                    } else {
                         print("No Response")
                    }
                    
                }).resume()
                
            }) {
                Text("Login")
                    .padding(10)
                    .frame(minWidth: 0, maxWidth: .infinity)
                    .font(.system(size: 22))
                    .foregroundColor(Color(UIColor(hexString: "#006622")))
                    .overlay(
                    RoundedRectangle(cornerRadius: 40)
                        .stroke(Color.black, lineWidth: 1))
           
                
            }.padding([.top],40)
             

            if self.status == 0 {
                Text(self.message)
                .foregroundColor(.red)
                .font(.system(size: 20))
                .padding([.top],30)
            }
            
            
            Spacer()
        }.padding()

        }
     }
    }
}
user1591668
  • 2,591
  • 5
  • 41
  • 84
  • 2
    Does this answer your question? [SwiftUI NavigationLink: Navigate to a destination view AFTER running account creation code successfully](https://stackoverflow.com/questions/57697827/swiftui-navigationlink-navigate-to-a-destination-view-after-running-account-cre) – bde.dev Jul 06 '20 at 17:45

2 Answers2

2

Try this (scratchy - not tested because not compilable due to absent dependencies), so adapt at your side:

struct ContentView: View {
    @State var email: String = ""
    @State var password: String = ""
    @State var message: String = ""
    @State var status: Int = -10
    @State var showActive = false      // << seems this state, so false
 
    var body: some View {

        NavigationView {
        ZStack {
            
           Color(UIColor.systemGroupedBackground)
            .edgesIgnoringSafeArea(.all)
            
           
        VStack(alignment: .center) {
      
            Spacer()
            
            TextField("Email", text: $email)
                .padding(10)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .background(Color(UIColor(hexString: ForestGreen)))
                .foregroundColor(Color.black)
            
            SecureField("Password", text: $password)
                .padding(10)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .background(Color(UIColor(hexString: ForestGreen)))
                .foregroundColor(Color.black)

             
            Button(action: {
                guard  let url = URL(string:ConnectionString+"profile/login") else { return }
                let parameter = "email=\(self.email)&password=\(self.password)"
                let request = RequestObject(AddToken: true, Url: url, Parameter: parameter)
                
                URLSession.shared.dataTask(with:request, completionHandler: {(data, response, error) in
                    if let decode = try? JSONDecoder().decode(ProfileCodable.self, from: data!)
                    {
                        self.status = decode.status ?? -10
                        self.message = decode.message ?? ""
                        if decode.status == 0 {
                            print("Invalid Credentials")
                        } else if decode.status == 1 {
                
                           self.showActive = true             // << here !!
                            
                        } else if decode.status == -1 {
                            print("Error")
                        }
                        
                    } else {
                         print("No Response")
                    }
                    
                }).resume()
                
            }) {
                Text("Login")
                    .padding(10)
                    .frame(minWidth: 0, maxWidth: .infinity)
                    .font(.system(size: 22))
                    .foregroundColor(Color(UIColor(hexString: "#006622")))
                    .overlay(
                    RoundedRectangle(cornerRadius: 40)
                        .stroke(Color.black, lineWidth: 1))
           
                
            }.padding([.top],40)
            .background(
               // activated by state programmatically !!
               NavigationLink(destination: MainView(), isActive: $self.showActive) {
                  EmptyView()     // << just hide
               }.buttonStyle(PlainButtonStyle())
            )


            if self.status == 0 {
                Text(self.message)
                .foregroundColor(.red)
                .font(.system(size: 20))
                .padding([.top],30)
            }
            
            
            Spacer()
        }.padding()

        }
     }
    }
}
Asperi
  • 228,894
  • 20
  • 464
  • 690
1

Simply use the isActive property of navigation link. It would look like this:

NavigationLink(destination: MainView(), isActive: $mainViewActive) {
     Text("Press on me")
}.buttonStyle(PlainButtonStyle()) 

and you should also declare the variable in your view:

@State var mainViewActive = false

then on successful login simply change the value to true. If you also do not want to display an actual link use EmptyView() as wrapper. So it would look like this:

NavigationLink(destination: MainView(), isActive: $mainViewActive) {
     EmptyView()
}
bde.dev
  • 729
  • 9
  • 9