Skip to content

Instantly share code, notes, and snippets.

@jbnunn
Last active May 16, 2024 07:39
Show Gist options
  • Save jbnunn/dab656b53f6e4ee2f53730f0b8daee64 to your computer and use it in GitHub Desktop.
Save jbnunn/dab656b53f6e4ee2f53730f0b8daee64 to your computer and use it in GitHub Desktop.
SwiftUI + PhoneNumberKit implementation
import SwiftUI
import UIKit
import PhoneNumberKit
struct PhoneNumberTextFieldView: UIViewRepresentable {
@Binding var phoneNumber: String
private let textField = PhoneNumberTextField()
func makeUIView(context: Context) -> PhoneNumberTextField {
textField.withExamplePlaceholder = true
//textField.font = UIFont(name: GlobalConstant.paragraphFont.rawValue, size: 17)
textField.withFlag = true
textField.withPrefix = true
// textField.placeholder = "Enter phone number"
textField.becomeFirstResponder()
return textField
}
func getCurrentText() {
self.phoneNumber = textField.text!
}
func updateUIView(_ view: PhoneNumberTextField, context: Context) {
}
}
struct SignUpSignInView: View {
@State private var phoneNumber = String()
@State private var validationError = false
@State private var errorDesc = Text("")
@State private var phoneField: PhoneNumberTextFieldView?
let phoneNumberKit = PhoneNumberKit()
var body: some View {
ZStack {
VStack(alignment: .leading) {
Text("Sign in with your phone number")
self.phoneField
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 60)
.keyboardType(.phonePad)
Button(action: {
do {
self.phoneField?.getCurrentText()
print("phone is: \(self.phoneNumber)")
let validatedPhoneNumber = try self.phoneNumberKit.parse(self.phoneNumber)
print("Validated Number: \(validatedPhoneNumber)")
// Integrate with your login/registration system here...
}
catch {
self.validationError = true
self.errorDesc = Text("Please enter a valid phone number")
}
}) {
Text("Sign in")
}
.padding(15)
Spacer()
}
.padding()
.onAppear {
self.phoneField = PhoneNumberTextFieldView(phoneNumber: self.$phoneNumber)
}
.alert(isPresented: self.$validationError) {
Alert(title: Text(""), message: self.errorDesc, dismissButton: .default(Text("OK")))
}
}
}
}
@CodyBontecou
Copy link

I have a login view and a signup view. The login view has a button to signup, the signup view has a button to go back to the login view.

If I go from login -> signup, this field works.

But if I go from login -> signup -> login -> signup, the text field no longer recognizes my input and believes it's always empty. Any ideas as to why this is happening?

@roip890
Copy link

roip890 commented Aug 14, 2020

Hi, I want to suggest an improvement that more compatible to SwiftUI:

import SwiftUI
import UIKit
import PhoneNumberKit

struct PhoneNumberField: UIViewRepresentable {
    
    @Binding var phoneNumber: String
    private let textField = PhoneNumberTextField()
 
    func makeUIView(context: Context) -> PhoneNumberTextField {
        textField.withExamplePlaceholder = true
        textField.withFlag = true
        textField.withPrefix = true
        textField.placeholder = "Phone"
        textField.becomeFirstResponder()
        textField.addTarget(context.coordinator, action: #selector(Coordinator.onTextUpdate), for: .editingChanged)
        return textField
    }
    
    func updateUIView(_ view: PhoneNumberTextField, context: Context) {

    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    class Coordinator: NSObject, UITextFieldDelegate {

        var control: PhoneNumberField

        init(_ control: PhoneNumberField) {
            self.control = control
        }

        @objc func onTextUpdate(textField: UITextField) {
            self.control.phoneNumber = textField.text!
        }

    }

}

@fogonthedowns
Copy link

Hi, I want to suggest an improvement that more compatible to SwiftUI:

import SwiftUI
import UIKit
import PhoneNumberKit

struct PhoneNumberField: UIViewRepresentable {
    
    @Binding var phoneNumber: String
    private let textField = PhoneNumberTextField()
 
    func makeUIView(context: Context) -> PhoneNumberTextField {
        textField.withExamplePlaceholder = true
        textField.withFlag = true
        textField.withPrefix = true
        textField.placeholder = "Phone"
        textField.becomeFirstResponder()
        textField.addTarget(context.coordinator, action: #selector(Coordinator.onTextUpdate), for: .editingChanged)
        return textField
    }
    
    func updateUIView(_ view: PhoneNumberTextField, context: Context) {

    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    class Coordinator: NSObject, UITextFieldDelegate {

        var control: PhoneNumberField

        init(_ control: PhoneNumberField) {
            self.control = control
        }

        @objc func onTextUpdate(textField: UITextField) {
            self.control.phoneNumber = textField.text!
        }

    }

}

Wow! This is exactly what I spent hours researching - nice idea adding a separate Class

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment