chronotruck / FlagPhoneNumber

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

When flag images aren't showing the alternative unknown flag doesn't appear #123

Closed lsamaria closed 4 years ago

lsamaria commented 4 years ago

For some reason when I have a programmatic collectionView and I present the vc with the FPNTextField class the flag doesn't appear.

Screen Shot 2019-09-18 at 6 15 04 PM

Another problem as you can see in the photo above, the unknown image in your asset catalog doesn't appear in either the FPNTextField at the top nor the FPNCountryPicker at the bottom. When I look into the asset folder these are the errors I see:

Screen Shot 2019-09-18 at 6 16 28 PM

Screen Shot 2019-09-18 at 6 16 51 PM

In the FPNCountry file when the images get loaded, if an image can't be found the unknown image is provided as a fallback image but there isn't an alternative for the unknown image

Screen Shot 2019-09-15 at 11 38 56 PM

I tried this fix (red arrow in below pic) for the asset catalog warning but nada.

Screen Shot 2019-09-20 at 9 42 25 PM

As for as the initial problem itself I don't have the problem with any other classes that present the vc with the FPNTextField because all the flags appear. All my code is programmatic so it's easy to just c+p and move the presenter code around. The problem only happens in classes with a collectionView. I narrowed it down to the constraints, for whatever reason the cv constraints in one class somehow affects the flags in another class. These are the constraints I use:

collectionView.translates.... = false
view.addSubview(collectionView)

collectionView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
collectionView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 0).isActive = true
collectionView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: 0).isActive = true
collectionView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true.

I also tried setting the cv size to view.bounds when I instantiate it but the same problem occurred:

lazy var collectionView: UICollectionView = {

    let layout = UICollectionViewFlowLayout()
    layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)

    let collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: layout)
    collectionView.delegate = self
    collectionView.dataSource = self
    collectionView.alwaysBounceVertical = true
    // ...
    collectionView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
    collectionView.scrollIndicatorInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
    return collectionView
}()

This problem occurs wether pushing on presenting.

To Reproduce

Create a programmatic collectionView with the same constraints I used above. Add a barButtonItem and for it's target action either push or present another vc that contains the FPNTextField

Expected behavior The flags should appear and when they don't the unknown image should appear

Screenshots see above

Smartphone (please complete the following information): iPhone 7+ and all the simulator iPhones and iPads

FlagPhoneNumber (please complete the following information):

Additional context Add any other context about the problem here.

grifas commented 4 years ago

Can you test with the fix_layout branch ?

lsamaria commented 4 years ago

I’ll try it later tonight and get back to you.

Btw I got it to work with the Apple emoji. I just had to clean the derived data after changing the code.

lsamaria commented 4 years ago

I haven’t had a chance to get to it yet. I’m working on 3 apps and hoping to release them this week. Once I get them to the AppStore I’ll immediately jump on top of this.

lsamaria commented 4 years ago

I finally got a chance to download the new Podfile. You fixed the issue, thanks!!!

venkateshwarlut commented 1 year ago

@lsamaria can you please tell me which pod version fixed ??? currently I'm suing 0.8.0 not working for me.

lsamaria commented 1 year ago

@venkateshwarlut This pod is no longer supported. The last commit was Dec 2019. I switched to phoneNumberKit. It's very easy to use. Let me know if you need some help setting up, I'll send some code.

venkateshwarlut commented 1 year ago

@

@venkateshwarlut This pod is no longer supported. The last commit was Dec 2019. I switched to phoneNumberKit. It's very easy to use. Let me know if you need some help setting up, I'll send some code.

Yes please share me sample code. I will check and setup.

lsamaria commented 1 year ago

@venkateshwarlut

In checkPhoneNumberValidity() you want to check if isNumberValid ... then do whatever with all of the info

import PhoneNumberKit

lazy var phoneNumberTextField: PhoneNumberTextField = {
        let textField = PhoneNumberTextField()
        textField.translatesAutoresizingMaskIntoConstraints = false
        textField.font = UIFont.systemFont(ofSize: 19)
        textField.textColor = UIColor.black
        textField.autocorrectionType = .no
        textField.keyboardType = .phonePad
        textField.layer.borderWidth = 1
        textField.layer.borderColor = UIColor.black.cgColor
        textField.layer.cornerRadius = 5
        textField.inputAccessoryView = UIView() // hides Done button from keyboard
        textField.withPrefix = true
        textField.withExamplePlaceholder = true
        textField.withFlag = true
        textField.withDefaultPickerUI = true
        textField.addTarget(self, action: #selector(checkPhoneNumberValidity), for: .editingChanged)
        return textField
}()

var phoneNumberKit: PhoneNumberKit!

override func viewDidLoad() {
        super.viewDidLoad()

        phoneNumberKit = PhoneNumberKit()
}

deinit {
        phoneNumberKit = nil
}

@objc func checkPhoneNumberValidity() {

        guard let textFieldText = phoneNumberTextField.text else { return }

        guard let phoneNumberKit = phoneNumberKit else { return }

        do {

            let phoneNumber = try phoneNumberKit.parse(textFieldText)

            let numberString = phoneNumber.numberString
            let countryCode = phoneNumber.countryCode
            let nationalNumber = phoneNumber.nationalNumber
            let numberExtension = phoneNumber.numberExtension
            let type = phoneNumber.type

            print("\nnumberString: \(numberString) | countryCode: \(countryCode) | nationalNumber: \(nationalNumber) | numberExtension: \(numberExtension as Any) | type: \(type)")

            let formattedPhoneNumberStr = phoneNumberKit.format(phoneNumber, toType: .e164)
            print("formattedPhoneNumberStr: \(formattedPhoneNumberStr)\n")

            if let regionCode = phoneNumberKit.mainCountry(forCode: countryCode) {

                //let country = Locale.current.localizedString(forRegionCode: regionCode)
                //print("\nregionCode: \(regionCode) | country: \(country as Any)\n")

                let countryCodePlusNationalNumber = String(countryCode) + String(nationalNumber)
                print("countryCodePlusNationalNumber: \(countryCodePlusNationalNumber)\n")

                let isNumberValid = phoneNumberKit.isValidPhoneNumber(countryCodePlusNationalNumber, withRegion: regionCode, ignoreType: true)
                if isNumberValid {

                    print("valid phone number")

                } else {

                    print("invalid phone number")
                }

            } else {
                print("regionCode is nil")
            }

        } catch {
            print("Generic parser error: ", error.localizedDescription)
        }
}