Home

Awesome

CountryPickerView

Build Status Platform Version Carthage compatible SPM compatible License

CountryPickerView is a simple, customizable view for selecting countries in iOS apps.

You can clone/download the repository and run the demo project to see CountryPickerView in action. First run pod install from the CountryPickerViewDemo directory.

<img align="left" src="https://raw.githubusercontent.com/kizitonwose/CountryPickerView/master/CountryPickerViewDemo/Screenshots/1.png" width="300"> <img src="https://raw.githubusercontent.com/kizitonwose/CountryPickerView/master/CountryPickerViewDemo/Screenshots/2.png" width="300"> <img align="left" src="https://raw.githubusercontent.com/kizitonwose/CountryPickerView/master/CountryPickerViewDemo/Screenshots/3.png" width="300"> <img src="https://raw.githubusercontent.com/kizitonwose/CountryPickerView/master/CountryPickerViewDemo/Screenshots/4.png" width="300">

Installation

Note that 3.x releases are Swift 5 compatible. For the Swift 4 compatibility, use 2.x releases. For the Swift 3 compatibility, use 1.x releases.

Swift Package Manager

Swift Package Manager is a dependency manager built into Xcode.

If you are using Xcode 11 or higher, go to File / Swift Packages / Add Package Dependency… and enter package repository URL https://github.com/kizitonwose/CountryPickerView.git then follow the instructions.

Cocoapods

CountryPickerView is available through CocoaPods. Simply add the following to your Podfile:

use_frameworks!

target '<Your Target Name>' do
  pod 'CountryPickerView'
end

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.

To install CountryPickerView through Carthage, simply add the following to your Cartfile:

github "kizitonwose/CountryPickerView"

Manual

  1. Put CountryPickerView repo somewhere in your project directory.
  2. In Xcode, add CountryPickerView.xcodeproj to your project.
  3. On your app's target, add the CountryPickerView framework:
    1. as an embedded binary on the General tab.
    2. as a target dependency on the Build Phases tab.

Usage

If you're using Storyboards/Interface Builder you can create a CountryPickerView instance by adding a UIView to your Storyboard, and then manually changing the view's class to CountryPickerView in the "Custom Class" field of the Identity Inspector tab on the Utilities panel (the right-side panel)

You can also create an instance of CountryPickerView programmatically:

import CountryPickerView

let cpv = CountryPickerView(frame: /**Desired frame**/)

To get the selected country from your CountryPickerView instance at any time, use the selectedCountry property.

let country = cpv.selectedCountry
print(country)

This property is not optional, the default value is the user's current country, derived from the device's current Locale.

Customization

Customization options for the view itself are available directly via the CountryPickerView instance while options for the internal CountryPicker table view are available via the CountryPickerViewDataSource protocol. Setting the CountryPickerViewDelegate protocol is also necessary if you wish to be notified when the user selects a country from the list.

import CountryPickerView

class DemoViewController: UIViewController, CountryPickerViewDelegate, CountryPickerViewDataSource {

    @IBOutlet weak var countryPickerView: CountryPickerView!

    override func viewDidLoad() {
        super.viewDidLoad()

        countryPickerView.delegate = self
        countryPickerView.dataSource = self
    }
}

CountryPickerView properties

PropertyDescriptionDefault value
showCountryCodeInViewShow or hide the country code(e.g NG) on the view.true
showPhoneCodeInViewShow or hide the phone code(e.g +234) on the view.true
showCountryNameInViewShow or hide the country name(e.g Nigeria) on the view.false
fontThe font of the phone/country code text.system font
textColorThe color of the phone/country code text.black
flagSpacingInViewThe spacing between the flag image and the phone code text.8px
hostViewControllerThe view controller used to show the internal CountryPickerViewController. If this is an instance of UINavigationController, the CountryPickerViewController will be pushed on the stack. If not, the CountryPickerViewController will be presented on its own navigation stack. If this property is nil, the view will try to find the nearest view controller and use that to present or push the CountryPickerViewController.nil
delegateAn instance of CountryPickerViewDelegate type.nil
dataSourceAn instance of CountryPickerViewDataSource type.nil

Note: The properties showCountryCodeInView and showCountryNameInView can't both be enabled at the same time. Enabling one to will disable the other. You can only show all properties on the list(see CountryPickerViewDataSource).

CountryPickerViewDelegate

Note: If you already have a Country class or struct in your project then implementing the didSelectCountry delegate method can cause a compile error with a message saying that your conforming class does not comform to the CountryPickerViewDelegate protocol. This is because Xcode can't figure out which Country model to use in the method. The solution is to replace the Country in the method signature with the typealias CPVCountry, your delegate method should now look like this:

func countryPickerView(_ countryPickerView: CountryPickerView, didSelectCountry country: CPVCountry)

You can also use CPVCountry as a replacement for the framework's Country model in other parts of your project.

Also, willShow and didShow delegate methods are optional. If the CountryPickerViewController is presented(not pushed), it is embedded in a UINavigationController. The CountryPickerViewController class is made available so you can customize its appearance if needed. You can also access the public searchController(UISearchController) property in the CountryPickerViewController for customization.

CountryPickerViewDataSource

The datasource methods define the internal(country list) ViewController's behavior. Run the demo project to play around with the options. All methods are optional.

Using CountryPickerView with UITextField

A good use case for CountryPickerView is when used as the left view of a phone number input field.

class DemoViewController: UIViewController {

    @IBOutlet weak var phoneNumberField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        let cpv = CountryPickerView(frame: CGRect(x: 0, y: 0, width: 120, height: 20))
        phoneNumberField.leftView = cpv
        phoneNumberField.leftViewMode = .always
    }
}

This means your users do not have to worry about entering the country's phone code in the text field. This also ensures you get a valid phone code from CountryPickerView instead of relying on your users.

Using the internal picker independently

If for any reason you do not want to show the default view or have your own implementation for showing country information, you can still use the internal picker to allow your users select countries from the list by calling the method showCountriesList(from: UIViewController) on a CountryPickerView instance.

It's important to keep a field reference to the CountryPickerView instance else it will be garbage collected and any attempt to use it will result to a crash.

class DemoViewController: UIViewController {

    // Keep a field reference
    let countryPickerView = CountryPickerView()

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func buttonPressed(_ sender: Any) {
        countryPickerView.showCountriesList(from: self)
    }
}

In the example above, calling countryPickerView.showCountriesList(from: self) will result in the internal picker view controller being presented in its own navigation stack because DemoViewController is not a navigation controller.

If you already have a navigation stack, you can push the internal picker view controller onto that stack by calling countryPickerView.showCountriesList(from: self.navigationController!) or do it the safe way:

if let nav = self.navigationController {
	countryPickerView.showCountriesList(from: nav)
}

Don't forget to set a delegate to be notified when the use selects a country from the list. An example of how to use the internal picker view controller is included in the demo project.

Creating Country instances

You can create Country instances with any of these methods in CountryPickerView class:

let countryPickerView = CountryPickerView()
let country = countryPickerView.getCountryByName("Nigeria")
let country2 = countryPickerView.getCountryByCode("NG")
let country3 = countryPickerView.getCountryByPhoneCode("+234")

You can also set the selected country using these helper methods:

let countryPickerView = CountryPickerView()
countryPickerView.setCountryByName("Nigeria")
countryPickerView.setCountryByCode("NG")
countryPickerView.setCountryByPhoneCode("+234")

License

CountryPickerView is distributed under the MIT license. See LICENSE for details.