iosclassif-statementswiftuipresentmodalviewcontroller

Present a new view when a condition has been met in SwiftUI


Hi everyone I'm new to SwiftUI .. I need to present a view containing two textFields with modal presentation only after a condition has been checked.


Example .. When the user pushes the login button I need the app to check the database for the existence of the user. If the user exists he can access the app otherwise he must show a view where he must enter his name and surname.

With UIKit I used this to present a structure or class

self.present(userFound ? Home() : UserNameInfo(), animated: true, completion: nil)

but with SwiftUI I can't figure out how to solve this problem.

Can you help me in any way?

My code

 var body: some View {
        
        ZStack(alignment: .top) {
            
            Color(.black).ignoresSafeArea()
            
            gradientBackground().ignoresSafeArea()

            VStack(alignment: .center, spacing: 25) {
                
                Spacer()
               
                logoStack()
                
                // Messaggio di benvenuto
                VStack(alignment: .leading, spacing: 15) {
                    
                    Text("Effettua l'accesso al tuo account")
                        .font(.title2.bold())
                   
                    Text("Riserva un momento esclusivo prenotando un taglio tradizionale oppure una rasatura con panni caldi e trattamenti viso")
                        .font(.callout.weight(.light))
                }
                .foregroundColor(.white)
                //.dynamicTypeSize(.medium)
                
                // Apple Sign In  Button
                SignInWithAppleView()
                    .frame(width: screen.size.width - 56)
                    .frame(height: 45, alignment: .center)
                    .onTapGesture(perform: showAppleLoginView)
                                
                // Divisore
                Divider().background(.gray)

                // Messaggio sull'accettazione della Privacy e delle Condizioni di utilizzo
                VStack(spacing: 5) {
                    Text("Continuando dichiaro di accettare le ")
                        .multilineTextAlignment(.center)
        
                    HStack(spacing: 0) {
                        Button("Condizioni di Utilizzo") {}
                        .foregroundColor(.white)
                        .font(.footnote.bold())
        
                        Text(" ed i ")
        
                        Button("Termini sulla Privacy") {}
                        .foregroundColor(.white)
                        .font(.footnote.bold())
        
                        Text(".")
                    }
                }
                .foregroundColor(.gray)
                .font(.footnote)
                .padding(.bottom, 25)

            }
            .padding(.horizontal)
        }

    private func showAppleLoginView() {
        
      // Show modalview if user not exist in Firebase
    }

// MARK: - Apple Sign In Button View Representable
struct SignInWithAppleView: UIViewRepresentable {
    
    typealias UIViewType = ASAuthorizationAppleIDButton
    
    func makeUIView(context: Context) -> UIViewType {
        ASAuthorizationAppleIDButton(type: .signIn, style: .white)
    }
    
    func updateUIView(_ uiView: UIViewType, context: Context) {}
}

Solution

  • You can use the modifier .fullScreenCover

    & you just need to pass a binding to a @State var which you set to true when you want to display the modal.

    example

    struct ExampleScreenView: View {
        @State var showModal: Bool = false
    
        var body: some View {
            VStack {
                Text("Some Text")
                    .padding()
    
                Button {
                    showModal = true
                } label: {
                    Text("Show other view")
                }
            }
            .fullScreenCover(isPresented: $showModal) {
                VStack {
                    Color.white
                    Text("Some other text")
                        .padding()
    
                    Button {
                        showModal = false
                    } label: {
                        Text("close view")
                    }
                }
            }
        }
    }
    

    This example the first view has a button that sets the bool to true, and shows the modal, the modal view has a button that sets the bool to false and closes the view.

    The button is just for the sake of an example, but you can use any logic to set the bool. to true, and then you can present whatever view you choose within the fullScreenCover.

    Specific for the login scenario, you can use a .onReceive modifier to listen for a notification sent from your login successful code.

    .onReceive(NotificationCenter.default.publisher(for: Notification.Name(rawValue: "didLogin"))
    

    &

    NotificationCenter.post(name:Notification.Name("didLogin"), object: nil)