Color Picker in iOS, iPadOS, and macOS
This post was originally published on my blog
WWDC 2020 brought many new UIControl APIs to iOS, iPadOS, and macOS. One of the best new additions is the system Color Picker. Here are some of the main features of this new control-
- Native- adapts to system fonts, themes.
- Powerful- Colors can be picked from 3 different modes and it provides a screen picker which can be used to pick colors from anywhere on the screen
- Transferable Pallets- Picked colors from the color picker can be accessed from anywhere.
- Universal- Available on iOS, iPadOS and with Catalyst on macOS
Let’s code
The first thing we’ll do is configure our parent view controller. For this example, we’ll change the background color of this view controller when the color picker view controller returns us a new color. We’ll store this color property in a variable called pickedColor
. Let us initially set its value to UIColor.systemTeal
because, fun fact, Teal is my favorite color. We have to create another property that is an object of the brand new UIColorPickerViewController
class. We’ll call this object colorPicker
.
Your class properties should now look like this:
private var pickedColor = UIColor.systemTeal
private var colorPicker = UIColorPickerViewController()
Creating a selectColor Function
This function will be used to configure and present the ColorPicker view controller on top of our parent view controller. Using the colorPicker variable we can access several properties of the CPVC such as setting the initial color, setting a settingAlpha boolean that will let users choose the opacity/alpha of the color. The function should now look like this
private func selectColor() {
colorPicker.supportsAlpha = true
colorPicker.selectedColor = pickedColor
self.present(colorPicker, animated: true)
}
Setting up the Bar Button
Our color picker view controller will be presented when we tap on the right bar button item in a navigation bar. For this, we’ll create a function that will set up the bar button and configure its action. We’ll first create a UIAction
that will call the selectColor()
function that we just built.
private func setupBarButton() {
let pickColorAction = UIAction(title: "Pick Color") { _ in
self.selectColor()
}
let pickColorBarButton = UIBarButtonItem(image: UIImage(systemName: "eyedropper"), primaryAction: pickColorAction)
navigationItem.rightBarButtonItem = pickColorBarButton
}
Wiring up the Delegates
UIColorPickerViewController contains a UIColorPickerViewControllerDelegate
that can inform the delegate on
- didSelectColor — User has picked a color
- didFinish- User has dismissed the color picker
To use these delegates we’ll extend the ViewController class and add conformance to the delegate. Below the closing bracket of the main class, declaration write this
extension ViewController: UIColorPickerViewControllerDelegate {
}
Both the above-mentioned delegate properties are optional but you’d want to use at least one of them. For this example, we’ll use both of the delegates just so that you understand when and how the delegate methods get called.
In the class, extension add these two delegate methods
func colorPickerViewControllerDidSelectColor(_ viewController: UIColorPickerViewController) {
}
func colorPickerViewControllerDidFinish(_ viewController: UIColorPickerViewController) {
}
The delegate method names are pretty self-explanatory as with all Swift APIs. In the didSelectColor method, we’ll first set the picked color to our pickedColor
variable and then set the value of the view’s background color to pickedColor. Simple
func colorPickerViewControllerDidSelectColor(_ viewController: UIColorPickerViewController) {
pickedColor = viewController.selectedColor
view.backgroundColor = pickedColor
}
You can choose to do this in the didFinish method as well but for this example I’ll simply put a print statement to print a message to our Xcode console when the view is dismissed.
func colorPickerViewControllerDidFinish(_ viewController: UIColorPickerViewController) {
print("Color Picker Controller Did Finish")
}
Configuring in viewDidLoad
Now that we have most of our app ready all we need to do is to set the initial background color of our view, configure the barButtonItem, and set the delegate. This is how my viewDidLoad method looks like
override func viewDidLoad() {
super.viewDidLoad()
colorPicker.delegate = self
setupBarButton()
view.backgroundColor = pickedColor
}
And that’s it. You now have a fully functioning, powerful, and native color picker that you can use anywhere in your app.
Thank you for reading this tutorial and if you have any questions feel free to ping me on twitter @SwapnanilDhol