Embed a UICollectionView Inside a UITableViewCell
That is, so it works
Before we start
Difficulty: Beginner | Easy | Normal | Challenging
This article has been developed using Xcode 12.2, and Swift 5.3
- You will be expected to be aware how to either make a Single View Application in Swift or use a Playground
- This article uses the Storyboard to implement the
UITableView, and then creates the
Keywords and Terminology
IndexPath: The path to a specific node in a tree of nested array collections
UICollectionView: An object that manages an ordered collection of data items and presents them using customizable layouts
UICollectionViewCell: The on-screen cell for the UICollectionView type
UITableView: A view that presents data using rows arranged in a single column
UITableViewCell: The visual representation of a single row in a table view
Creating great user interfaces should interest us all.
UIKit has some great advantages as a mature framework that developers are used to.
What this project is, and what it isn’t
As an example this project will display a
UITableView, and the
UITableViewCell instances will each contain a
UICollectionView that shold a
UICollectionViewCell that only displays a colour that has been predefined in the
This project doesn’t use an interesting architecture (I’d recommend MVVM-C and instead holds all of the data within the main
UIViewController instance. Therefore it is not ready for projection, and is more suited to a demonstration application that accompanies this article as a fully downloadable repo.
The look of the project
I’ve set up a rather bare-bones end project which has a
UITableView, with 5 rows each with a
UICollectionView (these have a blue background). Within this we have between 2 and 10
UICollectionViewCell instances that are of various colors.
When you click the
UICollectionViewCell instances they simply print the
indexPath to the screen.
The gotcha — let a UITableViewCell consume gesture
I always forget!
When you subclass a
UITableViewCell and want it to be able to consume gestures, you should set the property
isUsableInteractionEnabled to be true like this:
contentView.isUserInteractionEnabled = false
which can be written in the initializer for the subclass (the full subclass is detailled in the article).
The data is stored in a property that represents and Array of Arrays:
var data = [[UIColor.red, UIColor.green, UIColor.blue, UIColor.green, UIColor.purple, UIColor.orange, UIColor.blue, UIColor.green, UIColor.blue, UIColor.green], [UIColor.brown, UIColor.green], [UIColor.blue, UIColor.green], [UIColor.blue, UIColor.green], [UIColor.blue, UIColor.green]]
Note: I do apologise that I’ve called this ViewController, and that is not ideal.
So the most important part of this is that the
tableView...cellForRowAt that calls a function on the
which means that we need to look at the
Here the initializer has been overridden, which gives the opportunity to set up the
The initializer has the responsibility of setting up the instance of the
UICollectionView, and the
updateCellWith(row:) function injects data into the collection view, and to be clear this is a row of data (which in this case is an array of
The basic class looks like the following:
the extra section of code to make this work is an extension. This is the extension that creates the
UICollectionViewCell instances and sets up the data (which in this case is a
UIColor from the data property in
Of course it is more than possible to use a
UICollectionViewCell subclass and dequeue that from the collectionview, but unfortunately this is not quite within the scope of this project. We can, however, see the rather friendly print function that is within the
The Repo makes things rather easier to follow in this project, and I do recommend you download this project.
The fact is we are playing with code here, and trying to make sure that the Single Responsibility principle from the SOLID principles noted by Robert Cecil Martin and avoiding putting everything into one monster class, even when we have a
UICollectionView embedded in a
I hope this article has helped you, and of course has moved you forwards in your coding journey.
If you’ve any questions, comments or suggestions please hit me up on Twitter