Skip to content

Instantly share code, notes, and snippets.

@jbnunn
Last active June 6, 2024 08:52
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")))
}
}
}
}
@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

@hiasel
Copy link

hiasel commented Jun 5, 2024

were you guys able to show the country code picked?

I'm also wondering if anyone was able to make the country picker work in SwiftUI? The samples posted here work well but the country picker does not seem to be supported.

Update: It works perfectly fine by simply adding this line: textField.withDefaultPickerUI = true

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