iOS 14 — Modern Cell Configuration for Beginners (Programmatically)
Configurations let you focus on what you want to display without worrying about how to update all of your views.
0. Table of Content
- Introduction
- Create Table View
- How were we doing it before?
3.a. Legacy Implementation
3.b. Okay, but why has this needed an update? - How can we use Apple’s new API?
4.a. Modern Implementation
4.b. Okay, but what is better now?
4.c. How is this possible?
4.d. Keep in mind - Conclusion
- References
1. Introduction
In WWDC 2020, Apple has announced a brand new API to set up and configure cells in our table and collection views (and also stack views), which they call “Modern Cell Configuration”
In iOS 14, this new feature can be broadly separated into three categories:
· How we populate data,
· How we define the layout,
· How we display content.
I will implement the whole code without using the Main.storyboard, in other word programmatically.
We will focus on configuring the content and styling of the cells. I will use a default UITableView and a default UITableViewCell for simplicity. Once we get this done, I’m sure that you can implement the same idea by yourself with a little experimentation.
Even though we will implement pretty basic things, if you are new to UITableView or UICollectionView, I would highly recommend you to look at some examples before diving into this topic. Otherwise, you might feel confused.
2. Create Table View
You need to finish implementing TableView to see the result, so bear with me until the end.
Create a new project and save it wherever you want.
Below is how I implement the tableView, you can use your own style. It will have 10 rows and fill the whole view bound.
Then go ahead and create a new file inside the navigation controller name “CustomTableViewCell”. We won’t need awakeFromNib() and setSelected functions, so you can delete them.
3. How were we doing it before?
3.a. Legacy Implementation
Usually, programmers configure the reusable cell inside cellForRowAt function between cell variable and return statement like below:
cell.textLabel?.text = "Hello World"
cell.imageView?.image = UIImage(systemName: "bell")
3.b. Okay, but why has this needed an update?
Normally we have to check indexPath.row and handle some states and it can become very heavy to solve with a lot of redundant code in the view controller.
If (isSomething) do this styling, else if (isAnotherThing) do another styling, else do default styling. This can tire eyes and makes it hard to debug.
We were using “a reusable cell” but configuring it over and over again with each call. Unironically, we were not reusing the most repeated parts.
Plus, the processor has to do this check every time the cell is reused, which is a waste of energy and performance. This might not be a problem with 10 rows, but imagine 10,000 rows with infinite scroll… Things can get slow.
4. How can we use Apple’s new API?
4.a. Modern Implementation
What we are doing is:
- Declare a variable for default content configuration for the cell
- Modify that the default configuration using the API’s provided dot syntax.
- Assign default configuration to the cell’s content configuration.
Inside CutomTableViewCell.swift file add below updateConfiguration method.
Let’s break down each statement above.
- override func updateConfiguration(using state: UICellConfigurationState)
This function is called by the API for cells that are created for the tableView. It updates the cell’s configuration using the current state. It’s managed automatically behind the scene.
- super.updateConfiguration(using: state)
Since we are overriding a function, we should inherit all previously defined properties and functions so we don’t miss out on anything unknown or invisible to us.
- state
This indicates the possible states of the cell. It has a collection of traits. It can be Highlighted, Selected, any other custom states, etc. It has predefined variables and methods to be useful.
As in the example above, we change the style based on the state if it’s highlighted or selected.
- defaultContentConfiguration()
The default content configuration has preconfigured default styling but doesn’t contain any content. After you get the default configuration, you assign your content to it, customize any other properties, and assign it to the cell as the current contentConfiguration.
- backgroundConfiguration
The current background configuration of the cell.
UITableViewCell automatically sets up a default background configuration to provide its default appearance.
Using a background configuration, you can obtain system default background styling for a variety of different cell states. Create a background configuration with one of the default system styles, customize the configuration to match your cell’s style as necessary, and assign the configuration to this property.
- .updated(for: state)
Generates a configuration for the specified state by applying the configuration’s default values for that state to any properties that you haven’t customized.
- contentConfiguration = contentConfig and
backgroundConfiguration = backgroundConfig
This is the final step. contentConfig and backgroundConfig variables now contains our configurations. We need to assign them, to the cell configurations. Allowing the cell will use these two variables as content and background configurations.
As soon as we do this, the cell is updated to display the image, text, and background that we specified.
Please run and see how it goes.
4.b. Okay, but what is better now?
Now, before this line of code, setting the image and text only changed our local copy of the configuration stored in this “content” variable.
Because we’re using a content configuration, we never directly touch a UIImageView or UILabel. All of the properties are set on the configuration itself.
Well, for one, the code that we see here to configure a table view cell is almost the same code we would use to configure any cell. In fact, the same code works for any view that supports content configurations, even ones that aren’t cells, such as table view headers and footers.
Configurations are lightweight. We can use them as a source of default values for things like fonts, colors, and margins that you copy over to our custom views, even if we never apply the configuration directly itself.
For more advanced use cases, you can create a completely custom content configuration type with a paired content view class that renders it, and then use your custom configuration with any cell the same way that you would use a list content configuration.
And because the list content view is just a regular UIView, you can actually use it by itself anywhere, even outside of a collection or table view, such as in a plain UIStackView.
4.c. How is this possible?
This works because configurations are composable.
Instead of all of the functionality being baked into the cell class itself, like it was with UITableViewCell, these standard cell layouts and appearances are now available as independent pieces that can plug right into any cell or view that supports them.
4.d. Keep in mind
If you have existing code that you’re going to update and migrate over, configurations are mutually exclusive with some existing properties.
It seems that setting a background configuration always resets the background color and background view properties to nil. So make sure that you don’t mix a background configuration with other code still setting these other background properties on the same cell.
Content configurations replace the built-in subviews of cells, headers, and footers, like the imageView, textLabel, and detailTextLabel.
These legacy content properties seem to be eliminated in a future release, so Apple encourages us to adopt content configurations to take advantage of their more powerful features and enhanced customizability.
5. Conclusion
- Apple wants to put a standard API for one of the most used parts of their UIKit library, which we were doing manually until now. I think most of the developers were expecting something like this.
- New API will figure out what’s changed and efficiently update the views as needed.
- We may now assign default cell properties, and let the API handle the configurations. UIKit seems to handle the heavy lifting. Certainly, this will handle memory management better than the legacy way.
- Configurations act as a single source.
- It seems very easy to adopt.
- This new API has great potential.
6. References
- Apple Developer Documentation
- WWDC 2020
I hope that this article can be useful to you. Have a great one.