Skip to content

Instantly share code, notes, and snippets.

@jbnunn
Last active January 23, 2025 12:09
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")))
}
}
}
}
@vegadodo
Copy link

vegadodo commented Jan 23, 2025

Use more canonical and idiomatic Swift code if you are targeting iOS 13.0+

import SwiftUI
import PhoneNumberKit

struct PhoneNumberField: UIViewRepresentable {
    @Binding var text: String
 
    func makeUIView(context: Context) -> PhoneNumberTextField {
        let textField = PhoneNumberTextField()
        
        textField.withPrefix = true
        textField.withFlag = true
        textField.withExamplePlaceholder = true
        textField.withDefaultPickerUI = true
        
        textField.delegate = context.coordinator
        textField.becomeFirstResponder()
        return textField
    }
    
    func updateUIView(_ uiView: PhoneNumberTextField, context: Context) {
        uiView.text = text
        
        guard let phoneNumber = uiView.phoneNumber else {
            return
        }
        
        if phoneNumber.countryCode == 82, phoneNumber.type == .mobile, String(phoneNumber.nationalNumber).count != 10 {
            // Obsolete Korean mobile phone number
            // e.g. 011-123-4567
            return
        }
        
        DispatchQueue.main.async {
            uiView.resignFirstResponder()
        }
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    class Coordinator: NSObject, UITextFieldDelegate {
        var parent: PhoneNumberField

        init(_ parent: PhoneNumberField) {
            self.parent = parent
        }
        
        func textFieldDidChangeSelection(_ textField: UITextField) {
            if let text = textField.text {
                parent.text = text
            }
        }
    }
}

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