Swift 4.2 CaseIterable enums and UISegmentedControl, a practical example
Tags: swift, ios
Published: 2018-08-21 19:17:08

---
title: Swift 4.2 CaseIterable enums and UISegmentedControl, a practical example
published: true
tags: swift, ios
canonical_url: http://alejandromp.com/blog/2018/08/18/swift-42-caseiterable-enums-and-uisegmentedcontrol-a-practical-example/
---

On 2014 I wrote a [post](http://alejandromp.com/blog/2014/07/24/swift-enums/) about how to drive a UISegmentedControl with the new powerful Swift enums. Back then the major complain was that to get all the cases of the enum you had manually list the cases of the enum, which was tiresome and error prone.

This post is a new version of the same idea but updated to **Swift 4.2 and the new CaseIterable protocol.**

## <svg aria-hidden="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>CaseIterable

This new protocol has been introduced by the proposal [SE-0194](https://github.com/apple/swift-evolution/blob/master/proposals/0194-derived-collection-of-enum-cases.md). It defines a protocol with a single requirement, a `allCases` static variable that returns a collection with all possible values of the type.

But the best thing is that the compiler **automatically synthesises** the conformance for some simple `enum`s.

## <svg aria-hidden="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>Drive a UISegmentedControl

Let's first take a look at how the implementation looked back in 2014.

```
enum Size: Int, CustomStringConvertible {
    case S = 0
    case M
    case L
    case XL
    
    static func allValues() -> [String] {
        return [S, M, L, XL].map({$0.description})
    }
    
    static func count() -> Int {
        return allValues().count
    }
    
    public var description: String {
        switch self {
        case .S:
            return "S"
        case .M:
            return "M"
        case .L:
            return "L"
        case .XL:
            return "XL"
        }
    }
}

Size.count()
Size.allValues()

let segmented = UISegmentedControl(items: Size.allValues())
```

We can see how we need to implement a custom function and need to conform to `CustomStringConvertible`.

> Note that the CustomStringConvertible it's a tradeoff. We had to pick between implementing a custom `rawValue` or custom string.

Now with Swift 4.2 we can ged rid of both custom implementations leaving our modernised enum like this:

```
enum Size: Int, CaseIterable {
    case S = 0
    case M
    case L
    case XL
}
```

With just this conformance we get access to an automatically generated `allCases` variable.

The `CustomStringConvertible` can also be removed because Swift now provides better runtime information that allows String interpolation to access the name of the case.

With these improvements we have way less code to maintain and we can still drive our `UISegmentedControl` as before.

```
UISegmentedControl(items: Size.allCases.map({ "\($0)" }))
...
let index = sender.selectedSegmentIndex
Size(rawValue: index)
```

As usual you can find the code for this post in a [Playground](http://alejandromp.com/static/SwiftCaseIterable.playground-f80eab7fe171a4b3be19052556223af6.zip).

**If you want to know more about `CaseIterable` checkout my video on the topic: [Swift 4.2 - CaseIterable - Following Swift Evolution](https://youtu.be/c3W8-57Bdx8)**