[Swift] Building a selection list using Generics

Code in Swift
3 min readMar 13, 2022

Picking something out of a list of values is an incredibly common pattern in iOS. An application may have a dozen of screens like that. Manually writing them again and again is a lot of duplicated code that we don’t really need in our projects. What if we could create a generic view controller that could be reused across screens and projects to pick any kind of values?

The end result should be something like this, suitable to pick any kind of value:

We are going to support both kinds of lists: with icons and without. I’m going to omit most of the UICollectionView code in the snippets, but it is included in the sample project.

Selectable protocol

As we see on the screenshot above, the basic UI consists of a screen title and a value title. This is going to be the basis of our requirements for the Selectable protocol. We’ll also make it conform to Equatable protocol so that we can show and scroll to already selected value. It will also allow the caller of the list to understand which value was picked.

Now we need to conform our model to our protocol. But what if we have no specific model? What if we want to just pick a number? Do we pollute Int with our protocol conformance? What if we have two different screens both of which select numbers, what then?

Typealiases for selectable types

Turns out, that’s not really a problem. A great thing about Swift is that it not only has typealiases, but they can conform to protocols independently of their base type. So if we wanted, for example, to select from a list of Formula 1 seasons all we need to do is this.

To show how to support icons in the list we’ll add another model with information about Formula 1 championship kind.

Generic view controller

With the above in place we can start work on our generic UIViewController. We’ll need values and selectedValue properties for a list of possible values and the currently selected value respectively. These values will be displayed using UICollectionView, but as I said before, I won’t be including that code into the snippets.

Since our view controller works with any Selectable type, we add it as a type argument.

Returning selected value

Now we need a way to return the selected value back to the caller. Generic nature of our selection list makes using delegates for this task a little awkward. The better approach is a callback handler.

In the callback we need to return two values: the value that was picked and the SelectionListViewController itself, so that the caller can dismiss it.

Showing currently selected value

What if some value was already selected? We likely want to highlight it in the list and scroll to it automatically.

If it’s not a first item, we want to show the user that there are more items above the selected one. That’s why we scroll not to the selected item, but to the one directly above it.

Usage

With the above in place we’re ready to use our selection list. Let’s add some data to our Season model and see how we would invoke our SelectionListViewController

Now we can pick a season or championship of Formula 1 with just a few lines of code.

In a future article we’ll see if we can extend this solution to support loading values from API.

Check out sample code here.

If you liked this article please retweet it on Twitter or share it in any other social network. It helps more than you think!

--

--