2

I have two classes SubmitPhoneView and VerifyPhoneView.

For some reason, I noticed that whenever I input a digit into the textfield of SubmitPhoneView, it calls the init method of VerifyPhoneView. I want it to only be called once (when I press the continue button on SubmitPhoneView)

Why would this be?

Class SubmitPhoneView:

import SwiftUI
import Firebase

struct SubmitPhoneView: View {

    @State private var phoneNumber: String = ""
    @State private var verificationID : String = ""
    @State private var presentMe = false

    var body: some View {

        ZStack {

            Text("My number is")

            HStack(spacing: 20){
                Text("+1")

                TextField("Enter phone number", text: $phoneNumber)
                    .keyboardType(.numberPad)
            }

            VStack {

                NavigationLink(destination: VerifyPhoneView(phoneNumber: $phoneNumber.wrappedValue, verificationID: $verificationID.wrappedValue), isActive: $presentMe) { EmptyView() }

                Button(action: {
                    self.submitPhoneNumber()
                    self.presentMe = true
                }) {
                    Text("Continue")
            }
        }
    }

    func submitPhoneNumber() {
        PhoneAuthProvider.provider().verifyPhoneNumber("+1" + phoneNumber, uiDelegate: nil) { (verificationID, error) in
            if error != nil {
                print(error.debugDescription)
                return
            }
            else {
                self.verificationID = verificationID!
            }
        }
    }

}

Class VerifyPhoneView:

import SwiftUI
import Firebase

struct VerifyPhoneView: View {

    private var phoneNumber: String
    @State private var verificationID: String
    @State private var verificationCode: String = ""
    @State private var loginSuccesful: Bool = false
    @EnvironmentObject var ls: LoginStatus
    @EnvironmentObject var currentUser: CurrentUser

    init(phoneNumber: String, verificationID: String) {
        print("the init method was called for VerifyPhoneView")
        self.phoneNumber = phoneNumber
       _verificationID = State(initialValue: verificationID)
        print(self.verificationID)
    }

    var body: some View {

        ZStack {

            Text("My code is")

            TextField("Enter code", text: $verificationCode)

            Button(action: {
                self.submitVerificationCode()
            }) {
                Text("Continue")
            }

        }

    }

    func submitPhoneNumber() {
       // doesn't matter
    }

    func submitVerificationCode() {
       // doesn't matter
    }

    }    

}
ajf1000
  • 409
  • 5
  • 13
  • I changed the arguments in the navigationlink to hardcoded placeholders, and it seems like the init for the destination is only called once. So it seems like everytime the state for phonenumber changes, the destination init method is called. How can I stop this so it only happens when the continue button is pressed? – ajf1000 May 12 '20 at 02:27

1 Answers1

5

Use DeferView, as below

VStack {

    NavigationLink(destination: DeferView {
       VerifyPhoneView(phoneNumber: $phoneNumber.wrappedValue, verificationID: $verificationID.wrappedValue) 
    }, isActive: $presentMe) { EmptyView() }

    Button(action: {
        self.submitPhoneNumber()
        self.presentMe = true
    }) {
        Text("Continue")
}
Asperi
  • 228,894
  • 20
  • 464
  • 690
  • 1
    Just retested with Xcode 12GM / iOS 14GM - works as expected. – Asperi Sep 19 '20 at 04:58
  • I have created a separate [SO post](https://stackoverflow.com/questions/63985514/swiftui-onappear-called-multiple-times-because-of-navigationlink) that address the issue I'm having. It might be related, however the DeferView does not solve it. – Richard Witherspoon Sep 21 '20 at 02:41