WWDC20 is officially over, and iOS 14 is here, and with it came so many new features. Creating apps for all the Apple platforms is now one click away. I am so excited to share with you guys about all the new things introduced in WWDC20, starting with this article, there’s going to be so much more. So subscribe now to stay updated about my upcoming articles.
Note: For this tutorial, you will need Xcode 12, at the time of writing this article, Xcode 12 is available as a beta version for download on this link.
Let’s Start
I have kept this article simple and easy for you guys to follow, so in this project, we will be changing the background color of the UIView
on the basis of color selected by the user.
Create a new Xcode Project. Make sure you have selected Storyboard as Interface while creating the project and not SwiftUI.
UIColorPickerViewController
is a beautiful way of picking colors not just in iOS, but across all the Apple platforms, with this beauty, it’s so easy to use for a user, and with only a few lines of code, you can have your color picker running in your system. Let’s dive into an example now.
Open the Main.storyboard
file, and add a Button
in your ViewController.
Next, add two alignment constraints to the button. (Refer Screenshot)
Horizontally in Container
Vertically in Container
Next, create an action of your button, name it changeBackground
as mentioned in the image below
Enough of Storyboard, Now let’s move on to the Code.
Code
There are two ways of getting the selected color from the picker, one with the help of a delegate
, second with the help of Combine
. I love working with Combine
, but I’ll show you both ways of receiving the selected color.
Open your ViewController.swift
file, and in your newly created action changeBackground
, add the code shown below.
// Initializing Color Picker
let picker = UIColorPickerViewController()
// Setting the Initial Color of the Picker
picker.selectedColor = self.view.backgroundColor!
// Setting Delegate
picker.delegate = self
// Presenting the Color Picker
self.present(picker, animated: true, completion: nil)
In the code above, we have initialized the UIColorPickerViewController
with a preset color, so whenever the color picker is shown, the background color of the UIView
is shown as the selected color. Next, we set a delegate and the present it over our current view controller.
With this done, we need to add an extension at the bottom of our ViewController.swift
file. Add the code shown below.
extension ViewController: UIColorPickerViewControllerDelegate {
// Called once you have finished picking the color.
func colorPickerViewControllerDidFinish(_ viewController: UIColorPickerViewController) {
self.view.backgroundColor = viewController.selectedColor
}
// Called on every color selection done in the picker.
func colorPickerViewControllerDidSelectColor(_ viewController: UIColorPickerViewController) {
self.view.backgroundColor = viewController.selectedColor
}
}
Both the protocol functions are optional, and you can use them as per your convenience.
colorPickerViewControllerDidFinish(_:)
function is used to receive the callback once the user has completed the action of selecting the color and want to come back to the previous screen.
colorPickerViewControllerDidSelectColor(_:)
function is used to receive the callback on every selection of color done in the Color Picker.
So this was the delegate
way of receiving the user input, Now let's look at how we can achieve this with Combine
.
We no longer need the extension
which we just added for the demo purpose, nor we need to set a delegate
in the changeBackground
action function.
Combine
is available in almost all of your data types, I have already discussed this in my previous articles about Combine
. If you haven't read them, I'll recommend you to read them, and I'll drop a link at the end of this article to all the articles related to Combine
.
Let’s start with adding import Combine
on top of your ViewController.swift
file, so that we have access to the objects of Combine
framework.
Next, match your code with the code shown below.
// Global declaration, to keep the subscription alive.
var cancellable: AnyCancellable?
@IBAction func changeBackground(_ sender: Any) {
let picker = UIColorPickerViewController()
picker.selectedColor = self.view.backgroundColor!
// Subscribing selectedColor property changes.
self.cancellable = picker.publisher(for: \.selectedColor)
.sink { color in
// Changing view color on main thread.
DispatchQueue.main.async {
self.view.backgroundColor = color
}
}
self.present(picker, animated: true, completion: nil)
}
We have declared a global variable to keep receiving the changes published by the Publisher
, even when the changeBackground
function is not in scope.
Next, the change we have done in the changeBackground
function is subscribing the selectedColor
property with the help of KeyPath
.
Run the application.
Click Here to download the final project.
With the help of Combine
we can reduce our delegate function needs, and this also helps you maintain the code easily.
I hope you guys enjoyed reading my article. There’s a lot more to learn together, so subscribe to stay updated about my upcoming articles.
If you have any suggestions or questions, Feel free to connect me on Twitter or Reddit. 😉
To read articles related to Combine
, Click Here.