A simple, customizable view for efficiently collecting country information in iOS apps.

Overview

CountryPickerView

Build Status Platform Version Carthage 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.

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.

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

Property Description Default value
showCountryCodeInView Show or hide the country code(e.g NG) on the view. true
showPhoneCodeInView Show or hide the phone code(e.g +234) on the view. true
showCountryNameInView Show or hide the country name(e.g Nigeria) on the view. false
font The font of the phone/country code text. system font
textColor The color of the phone/country code text. black
flagSpacingInView The spacing between the flag image and the phone code text. 8px
hostViewController The 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
delegate An instance of CountryPickerViewDelegate type. nil
dataSource An 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

  • 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)
  • Called before the CountryPickerViewController is presented or pushed. The CountryPickerViewController is a UITableViewController subclass.

    func countryPickerView(_ countryPickerView: CountryPickerView, willShow viewController: CountryPickerViewController)
  • Called after the CountryPickerViewController is presented or pushed. The CountryPickerViewController is a UITableViewController subclass.

    func countryPickerView(_ countryPickerView: CountryPickerView, didShow viewController: CountryPickerViewController)

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.

  • 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 desired font for the section title labels on the list. Can be used to configure the text size.

    func sectionTitleLabelFont(in countryPickerView: CountryPickerView) -> UIFont
  • The desired text color for the section title labels on the list.

    func sectionTitleLabelColor(in countryPickerView: CountryPickerView) -> UIColor?
  • The desired font for the cell labels on the list. Can be used to configure the text size.

    func cellLabelFont(in countryPickerView: CountryPickerView) -> UIFont
  • The desired text color for the country names on the list.

    func cellLabelColor(in countryPickerView: CountryPickerView) -> UIColor?
  • The desired size for the flag images on the list.

    func cellImageViewSize(in countryPickerView: CountryPickerView) -> CGSize
  • The desired corner radius for the flag images on the list.

    func cellImageViewCornerRadius(in countryPickerView: CountryPickerView) -> CGFloat
  • 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 method only enables you return a button customized the way you want. Default value is nil

    func closeButtonNavigationItem(in countryPickerView: CountryPickerView) -> UIBarButtonItem?

    Note: Any target or action 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
  • Show the country code alongside the country name on the list. e.g Nigeria (NG). If true, searches are also performed against the country codes. Default value is false

    func showCountryCodeInList(in countryPickerView: CountryPickerView) -> Bool
  • Show a checkmark on the selected country on the list. Default value is true

    func showCheckmarkInList(in countryPickerView: CountryPickerView) -> Bool
  • The locale used to display country names on the list. Default value is the current locale.

    func localeForCountryNameInList(in countryPickerView: CountryPickerView) -> Locale

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.

Comments
  • Logo Proposal

    Logo Proposal

    Hello... Came across your very nice project and as logo designer who loves to contribute to open source projects, I want to help contribute by creating a unique logo for your project which will give it its own identity. Working on some cool logo design ideas currently... I will post the idea concepts here once i complete it, so you can give me your feedback to make any changes or tweak to suit your needs.

    opened by chimzycash 22
  • App Crashing

    App Crashing

    App crashing on select country after search the country from the list.

    Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present modal view controller on itself. Presenting controller is <UISearchController: 0x10c815e00>.' *** First throw call stack: (0x194802a48 0x194529fa4 0x19826ba80 0x19826dc6c 0x19826e168 0x19826dbbc 0x19826de24 0x1988e0958 0x198286600 0x198282d4c 0x198282a90 0x19887f128 0x19886ec78 0x19889eac8 0x19477fe68 0x19477ad54 0x19477b320 0x19477aadc 0x19e700328 0x198875ae0 0x10441f52c 0x194604360) libc++abi.dylib: terminating with uncaught exception of type NSException

    opened by arun-macrew 18
  • Why I get check icon next to country

    Why I get check icon next to country

    I press customCountry button which launches country list. For some strange issue I can see one country as already being checked... In some devices this country is in the middle of the list, and on some it is the first country.

    Also if I remove countries from list or add some, it also affects country List and makes a single country checked. I would like to know why some countries become selected even without pressing them? It is definitively a bug which really creates problems for our use case... I would like to contribute for fixing this version.

    opened by wellbranding 11
  • searchController is nil in willShow delegate method

    searchController is nil in willShow delegate method

    Hey! Is there a way to customize the searchBar in the willShow before the view appears? As I said, searchController is still nil in willShow delegate method, so I can only change it in didShow method with the expected style change when user is already on the view.

    opened by canedo2 10
  • Adds new customization to CountryPickerViewController through the ContryPickerViewDatasource

    Adds new customization to CountryPickerViewController through the ContryPickerViewDatasource

    • Added a method to allow to customize SectionHeaderTitleTextColor
    • Added a method to allow to customize the SearchBar background color. It also sets the background color of the UISearchViewController to the same color.
    opened by serjooo 10
  •  does not conform to protocol

    does not conform to protocol

    Hi, I'm using Xcode 9.2 and Swift 4 When I'm trying to implement delegate method didSelectCountry, I get the error:

    Type 'MBRegisterTableViewController' does not conform to protocol 'CountryPickerViewDelegate'

    but I already have

    func countryPickerView(_ countryPickerView: CountryPickerView, didSelectCountry country: Country) {}

    opened by antonkashpor 10
  • Search bar issue

    Search bar issue

    Hey 👋 first of all thank you for this library! I'm using the latest version on iOS 12.1 and the problem with searchbar still occurs (I saw that it was already closed here https://github.com/kizitonwose/CountryPickerView/issues/13). Can you fix it? :)

    image
    opened by bkucharskiDev 9
  • How to change padding in UIView?

    How to change padding in UIView?

    How can I change margin of country label and flag inside UIView which is used as CountryPickerView? Right now flag does not have any margin to the parent view..

    opened by wellbranding 8
  • Issue with black status bar

    Issue with black status bar

    I have a UI requirement to use a black background color for the status bar. For that, we need to use the status bar tint color as white. Is it possible to do that?

    File

    opened by sandeepbol 7
  • iOS13 freeze UITextField when using CountryPickerView

    iOS13 freeze UITextField when using CountryPickerView

    Update ios13, tap the UITextField with no responese. When i remove 'CountryPickerView', it's ok. I can't sure if that 'CountryPickerView' freeze UITextField in iOS13.

    屏幕快照 2019-10-15 下午1 55 47
    opened by cyjFS 6
  • Updated project to Swift 5.0

    Updated project to Swift 5.0

    • Protocol conformances to public protocols must conform to methods with a public identifier as well
    • Changed podspec file to update Swift version as well
    opened by serjooo 5
  • Custom SearchBar position

    Custom SearchBar position

    Description

    Custom position SearchBar (which being moved to the top and hidden when user roll cell) (Now the searchbar basing on tableViewHeader, then I need to set custom position search bar which not be hidden when I roll down). Simulator Screen Shot - iPhone 8 Plus - 2022-03-02 at 09 12 15

    opened by hmqq0123 0
  • after cancelling search header is not showing.

    after cancelling search header is not showing.

    Hi,

    Actually, I'm presenting VC. After clicking the cancel button, that Close button BackView is not showing.

    Here attaching the Video.

    https://user-images.githubusercontent.com/23524697/141965986-25fccda6-fb69-4d06-9a09-a56a37e4fbc5.mov

    Thank You.

    .

    opened by SreekanthGudisi 2
Releases(3.3.0)
Owner
Kizito Nwose
Android and iOS software developer.
Kizito Nwose
NotSwiftUI is designed to help you create UI components quickly and efficiently with code!

NotSwiftUI NotSwiftUI is designed to help you create UI components quickly and efficiently with code! Capitalizing on the idea that most of the UI ele

Jonathan G. 50 Dec 20, 2022
Swift based simple information view with pointed arrow.

InfoView View to show small text information blocks with arrow pointed to another view.In most cases it will be a button that was pressed. Example To

Anatoliy Voropay 60 Feb 4, 2022
Elissa displays a notification on top of a UITabBarItem or any UIView anchor view to reveal additional information.

Elissa Attach a local notification to any UIView to reveal additional user guidance. Usage Example Per default, Elissa will try to align to the center

null 169 Aug 14, 2022
Simple and highly customizable iOS tag list view, in Swift.

TagListView Simple and highly customizable iOS tag list view, in Swift. Supports Storyboard, Auto Layout, and @IBDesignable. Usage The most convenient

Ela Workshop 2.5k Jan 5, 2023
A beautiful radar view to show nearby items (users, restaurants, ...) with ripple animation, fully customizable

HGRippleRadarView Example To run the example project, clone the repo, and run pod install from the Example directory first. This project is inspired b

Hamza Ghazouani 352 Dec 4, 2022
Easy to use, highly customizable gauge view

GDGauge - Customizable Gauge View Requirements Xcode 11+ Swift 5 iOS 9+ Installation Swift Package Manager .package(url: "https://github.com/saeid/GDG

Saeid 74 Dec 5, 2022
The CITPincode package provides a customizable pincode view

The CITPincode package provides a customizable pincode view. It includes an optional resend code button with a built-in cooldown and an optional divider to be placed anywhere between the cells.

Coffee IT 3 Nov 5, 2022
Creating a simple selectable tag view in SwiftUI is quite a challenge. here is a simple & elegant example of it.

SwiftUI TagView Creating a simple selectable tag view in SwiftUI is quite a challenge. here is a simple & elegant example of it. Usage: Just copy the

Ahmadreza 16 Dec 28, 2022
A customizable color picker for iOS in Swift

IGColorPicker is a fantastic color picker ?? written in Swift. Table of Contents Documentation Colors Style Other features Installation Example Gettin

iGenius 272 Dec 17, 2022
Modular and customizable Material Design UI components for iOS

Material Components for iOS Material Components for iOS (MDC-iOS) helps developers execute Material Design. Developed by a core team of engineers and

Material Components 4.6k Dec 29, 2022
Customizable CheckBox / RadioButton component for iOS

GDCheckbox An easy to use CheckBox/Radio button component for iOS, with Attributes inspector support. Requirements Xcode 10+ Swift 5 iOS 9+ Installati

Saeid 23 Oct 8, 2022
A minimalistic looking banner library for iOS. It supports multiple customizable kinds of Banner types

A minimalistic looking banner library for iOS. It supports multiple customizable kinds of Banner types

Emre Armagan 12 Oct 10, 2022
A way to quickly add a notification badge icon to any view. Make any view of a full-fledged animated notification center.

BadgeHub A way to quickly add a notification badge icon to any view. Demo/Example For demo: $ pod try BadgeHub To run the example project, clone the r

Jogendra 772 Dec 28, 2022
Confetti View lets you create a magnificent confetti view in your app

ConfettiView Confetti View lets you create a magnificent confetti view in your app. This was inspired by House Party app's login screen. Written in Sw

Or Ron 234 Nov 22, 2022
📊 A customizable gradient progress bar (UIProgressView).

GradientProgressBar A customizable gradient progress bar (UIProgressView). Inspired by iOS 7 Progress Bar from Codepen. Example To run the example pro

Felix M. 490 Dec 16, 2022
Highly customizable Action Sheet Controller with Assets Preview written in Swift

PPAssetsActionController Play with me ▶️ ?? If you want to play with me, just tap here and enjoy! ?? ?? Show me ?? Try me ?? The easiest way to try me

Pavel Pantus 72 Feb 4, 2022
RangeSeedSlider provides a customizable range slider like a UISlider.

RangeSeekSlider Overview RangeSeekSlider provides a customizable range slider like a UISlider. This library is based on TomThorpe/TTRangeSlider (Objec

WorldDownTown 644 Dec 12, 2022
An easy to use UI component to help display a signal bar with an added customizable fill animation

TZSignalStrengthView for iOS Introduction TZSignalStrengthView is an easy to use UI component to help display a signal bar with an added customizable

TrianglZ LLC 22 May 14, 2022
Customizable School Timetable Library

JHTimeTable SwiftUI Customizable School TimeTable Library 설치 Swift Package Manager 사용하기 JHTimeTable뷰를 선언합니다. JHTimeTable(lineColor : .secondary,

LeeProgrammer 4 Jan 6, 2023