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.
Note that 2.x releases are Swift 4 compatible. For the Swift 3 compatibility, please use 1.x releases.
CountryPickerView is available through CocoaPods. Simply add the following to your Podfile:
use_frameworks!
target '<Your Target Name>' do
pod 'CountryPickerView'
end
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"
- Put CountryPickerView repo somewhere in your project directory.
- In Xcode, add
CountryPickerView.xcodeproj
to your project. - On your app's target, add the CountryPickerView framework:
- as an embedded binary on the General tab.
- as a target dependency on the Build Phases tab.
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 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
/*** Direct customizations on CountryPickerView instance ***/
// Show the selected country's phone(e.g +234) code on the view
countryPickerView.showPhoneCodeInView = true
// Show the selected country's iso code(e.g NG) on the view
countryPickerView.showCountryCodeInView = true
}
}
The delegate function will be called when the user selects a country from the list or when you manually set the selectedCountry
property of the CountryPickerView
func countryPickerView(_ countryPickerView: CountryPickerView, didSelectCountry country: Country) {
print(country)
}
The datasource functions define the internal(country list) ViewController's behavior. Run the demo project to play around with the options.
-
An array of countries you wish to show at the top of the list. This is useful if your app is targeted towards people in specific countries.
func preferredCountries(in countryPickerView: CountryPickerView) -> [Country]
-
The desired title for the preferred section.
func sectionTitleForPreferredCountries(in countryPickerView: CountryPickerView) -> String?
Note: You have to return a non-empty array of countries from
preferredCountries(in countryPickerView: CountryPickerView)
as well as this section title if you wish to show preferred countries on the list. Returning only the array or title will not work. -
Show ONLY the preferred countries section on the list. Default value is
false
func showOnlyPreferredSection(in countryPickerView: CountryPickerView) -> Bool
Return
true
to hide the internal list so your users can only choose from the preferred countries list. -
The navigation item title when the internal view controller is pushed/presented. Default value is
nil
func navigationTitle(in countryPickerView: CountryPickerView) -> String?
-
A navigation item button to be used if the internal view controller is presented(not pushed). If nil is returned, a default "Close" button is used. This function only enables you return a button customized the way you want. Default value is
nil
func closeButtonNavigationItem(in countryPickerView: CountryPickerView) -> UIBarButtonItem?
Note: Any
target
oraction
associated with this button will be replaced as this button's sole purpose is to close the internal view controller. -
Desired position for the search bar. Default value is
.tableViewHeader
func searchBarPosition(in countryPickerView: CountryPickerView) -> SearchBarPosition
Possible values are:
.tableViewHeader
,.navigationBar
and.hidden
-
Show the phone code alongside the country name on the list. e.g Nigeria (+234). Default value is
false
func showPhoneCodeInList(in countryPickerView: CountryPickerView) -> Bool
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.
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 function 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.
CountryPickerView is distributed under the MIT license. See LICENSE for details.