chronotruck / FlagPhoneNumber

A formatted phone number UITextField with country flag picker.
Apache License 2.0
438 stars 316 forks source link

Can it be used in SwiftUI ? #166

Open chittasec opened 4 years ago

chittasec commented 4 years ago

Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like A clear and concise description of what you want to happen.

Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.

Additional context Add any other context or screenshots about the feature request here.

mudassarahmad09 commented 4 years ago

Hi, are there a SwiftUI example of using FlagPhoneNumber?

mudassarahmad09 commented 4 years ago

Hi,

I've created a sample file "UIViewRepresentable" to use in SwiftUI.

struct FPNTextFieldViewHandler: UIViewRepresentable {

func makeUIView(context: Context) -> FPNTextField {
    let textField = FPNTextField()
    textField.delegate = context.coordinator
    textField.hasPhoneNumberExample = true
    return textField
}

func updateUIView(_ uiView: FPNTextField, context: Context) {

}

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

class Coordinator: NSObject, UITextFieldDelegate {
    var parent: FPNTextFieldViewHandler

    init(_ textField: FPNTextFieldViewHandler) {
        self.parent = textField
    }

}

} extension FPNTextFieldViewHandler.Coordinator : FPNTextFieldDelegate{ func fpnDidSelectCountry(name: String, dialCode: String, code: String) { print(name, dialCode, code) }

func fpnDidValidatePhoneNumber(textField: FPNTextField, isValid: Bool) {
    textField.rightViewMode = .always
    textField.keyboardType = .numberPad
}

func fpnDisplayCountryList() {

}

}

Hope its help somebody

tramert commented 4 years ago

@mudassarahmad09 Thanks so much for posting your SwiftUI compatible wrapper. I am struggling with figuring out how I can extract the text from the FPNTextFieldViewHandler.

What I would like to do is extract an E164 formatted number from the field but I cannot figure out where to put this logic and how I can call it. I have come to the conclusion I will likely have to modify the source code for FPNTextField but this is much more difficult than I imagined.

Do you have any insight on extracting the phone number for usage in the parent swiftUI view that is initializing FPNTextFieldViewHandler()?

Thanks in advance!

tramert commented 4 years ago

I modified the code above from @mudassarahmad09 to enable updating an "@State" variable in the view where PhoneNumberInput() is initialized.

import SwiftUI
import UIKit
import FlagPhoneNumber

struct PhoneNumberInput: View {
     @Binding var formattedPhoneNumber : String

    var body: some View {
        FPNTextFieldViewHandler(formattedPhoneNumber: self.$formattedPhoneNumber)
    }
}

struct PhoneNumberInput_Previews: PreviewProvider {
    @State static var value = ""

    static var previews: some View {
        PhoneNumberInput(formattedPhoneNumber: $value)
    }
}

struct FPNTextFieldViewHandler: UIViewRepresentable {
    @Binding var formattedPhoneNumber : String

    let textField = FPNTextField()

    func makeUIView(context: Context) -> FPNTextField {
        textField.delegate = context.coordinator
        textField.hasPhoneNumberExample = true
        return textField
    }

    func updateUIView(_ uiView: FPNTextField, context: Context) {
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(self, formattedPhoneNumber: $formattedPhoneNumber)
    }

    class Coordinator: NSObject, UITextFieldDelegate {
        @Binding var formattedPhoneNumber : String

        var parent: FPNTextFieldViewHandler

        init(_ textField: FPNTextFieldViewHandler, formattedPhoneNumber: Binding<String>) {
            self.parent = textField
            self._formattedPhoneNumber = formattedPhoneNumber
        }
    }
}

extension FPNTextFieldViewHandler.Coordinator : FPNTextFieldDelegate{
    func fpnDidSelectCountry(name: String, dialCode: String, code: String) {
        print(name, dialCode, code)
    }

    func fpnDidValidatePhoneNumber(textField: FPNTextField, isValid: Bool) {
        print("Phone number is valid: \(isValid)")
        if isValid {
            self.formattedPhoneNumber = textField.getFormattedPhoneNumber(format: FPNFormat.E164) ?? ""
        } else {
            self.formattedPhoneNumber = ""
        }
        textField.rightViewMode = .always
        textField.keyboardType = .phonePad
    }

    func fpnDisplayCountryList() {

    }
}
oskarko commented 2 years ago

is working fpnDisplayCountryList() in SwiftUI? In my case is never being called.

peter0bassem commented 1 month ago

is working fpnDisplayCountryList() in SwiftUI? In my case is never being called.

Did you find any solution do present countries list?

oskarko commented 1 month ago

is working fpnDisplayCountryList() in SwiftUI? In my case is never being called.

Did you find any solution do present countries list?

Sure, I did. I have created my own custom component for SwiftUI: https://github.com/oskarko/FlagPhoneNumberUI