Keeping Designers Happy via Enums

With more and more emphasis on “agile” development and “fast iteration cycles”, speed of development is commonly the most important KPI, which we all know can unfortunately have a direct impact on code quality and consistency. In this talk, Patrick shares how his team has leveraged Swift enums to manage app colors, fonts, and images in a way that has allowed the team to iterate more quickly while keeping code organized, and most importantly, maintain consistency.


Introduction (0:00)

I’m currently an iOS engineer at a company called Affirm. We’re a Fintech company building more honest and transparent financial services from the ground up, starting with short term loans. Before that I was at Adobe on a small prototyping team working really closely with designers to build products as fast as possible.

I wanted to share a little bit about that experience and the kinds of patterns that will help you get there too.

Should Designers Code? (3:00)

This talk was kind of birthed out of a question that comes up a lot in the design industry: “Should designers code?”

From the approach of “should designers code,” there’s a few things that designers have done that have made it much easier for a developer to implement a design.

The first was an eight pixel grid. I’ve worked with a few designers that have a rule that every element on the screen is aligned with an eight pixel or ten point grid, or some other defined number. This allows you as a developer to iterate very quickly.

If your designer follows the HIG, the Human Interface Guidelines, as closely as possible, that helps you as a developer because they’re not going into crazy designs that are really hard to implement.

I spend a lot of time with the designers I work with in Sketch. Sketch is organized and hierarchical and you can understand what components should live where and what all should be encapsulated in certain parts – it helps a developer work much more quickly.

Should Developers Design?

I don’t think the answer to this question is entirely true or false, but at least from a design perspective when I talk to designers these were things that they thought were helpful when working with developers. If developers were at least aware and open to these different patterns, it would be helpful.

Interaction design is one to be aware of, and it’s just really general animations, transitions, color.

Type - knowing when to use specific font styles. This includes styles such as regular versus medium versus italic. There needs to be a continuity between the deliverable and what they had in their designs.

How Enums Help Maintain Consistency (6:33)

When you are vetting a product very early on, it can be hard to be consistent with padding, spacing, and margins, and colors. Anything that can help you be consistent as you’re iterating and prototyping really quickly I’ve found really helpful from a design perspective as a developer.

Enums allow you to maintain consistency throughout your code and we’ll talk about the patterns that allow you to do that.

There’s a basic Enum, enumerated values, and then there’s raw values. In Swift they currently support assignment with maybe doubles or strings or something as well as associated values, and through each of these processes you can really help maintain consistency.

The three Enums:

  • Basic Enum
enum Movement {
  case Left
  case Right
  case Top
  case Bottom
}
  • Raw Values
enum Constants: Double {
  case π = 3.14159
  case e = 2.71828
  case Φ = 1.61803398874
  case λ = 1.30357
}
  • Associated Values
enum OptionalValue<T> {
  case None
  case Some<T>
}

Live Demo (7:30)

Check out the code samples for the live demo on Github

The Problem with Hard-Coded Styles

Early on in an app you find a lot of code that looks a certain way. If you’re setting a background color, you’ll set an explicit color. If you are using a font that looks great, you make it a heading font, and it has a size and a color. What happens at scale is that as you start to build out this app, you have very contextual, specific code, as well as strings that are scattered all over the place.

This becomes really hard to manage as your app scales.

If this code is not managed in a central place it can become pretty tough. I’ve gotten myself into some bad situations where you change one thing and then have an expectation that it will match in the other places and need to change those too, and it’s not as fun to work like that.

So What’s the Solution?

In open source, and in previous apps that I’ve worked on, there’s the notion of a style sheet. It’s typically a place where you’d put some of this UI logic around labels, images, fonts, and those types of things. This is something that’s helped us a lot in our past apps and it’s the approach that we’ve taken to structure this type of UI code.

Suppose we want to solve this problem where we have some type of container and we want to take some known color, like whiteColor, that’s defined in our container, and take it out into a style sheet instead.

We can say this is our white color and then create a variable for it. Then we can start to cbuild this out more until you start to inherit code into your UI from the style sheet. Once we have it in that context we can call our style sheet by color from our UI.

Benefits of Building Out a Style Sheet

As it starts to build out throughout the style sheet you can build up enums. Whether it’s colors, text, or images, as that starts to grow you can start to filter out this type of code from what sits in your UI.

So we have this notion of a default like heading font size. We may have a contextual location card - a card within another view. As we start to build out the color we can have a heading, subtitle, background, and within each of these enums we have specific colors that we can use. The associations between the actual hex value and what your color that you’re using in view all happens in one central place within your file.

This makes design really quick to change, and if your designer’s even remotely technical they can hop in and this can be the one file that they have the ability to touch. So as soon as you have a heading color that you need to change for example, you touch one spot here and it can update across other views, and your designer doesn’t have to know your view logic and that type of thing.

Dependency-Injection for Design

What I really would like is a pattern where it allows me to focus specifically on the data and let the style sheet manage the appearance. If I was working with a designer and I wanted to have the ability for them to hop in and start changing colors, they still currently would have to go in and touch these files.

We can override awakeFromNib, and we can go call our style sheet. This allows us to put a method, so we can have access to that cell. So if instead of setting our background color on our info container, we take that out and move that over into a style sheet, now we have a reference to a cell and set the background color in the style sheet.

Following this pattern starts to strip out a lot of that logic – the appearance logic that lives in the cell, out to a style sheet. If we were to build that you’d start to see the same effects. This is a form of dependency injection allowing a style sheet to manage what different properties it’s controlling.

This has helped me iterate really quickly because I can set up the core functionality of the app, the core data management, and it allows design to go in and make changes and not always have the back and forth that prolongs updates to the app.

Questions (19:14)

Q: In a more complicated app would you recommend styling the appearance proxies instead?

That could be a possibility. This is a really small-scale demo app. What we’ve found helps with scale is just name-spacing the style sheet. With Swift you can just write extensions of a style sheet, and it can live within the codebase in specific places. So if you have an extension on a stylesheet for just a location view, for example, it prevents your style sheet from getting bloated, because as soon as you have multiple views that could end up being one of your biggest files in your project. So extending those and making them a bit more isolated has helped in the past.

Q: How does this integrate with IB?

So at least this case the only place that IB is touching is that particular file, so you have to have references to the view itself. If you have a team that likes to do something entirely programmatic, chose to take a balance with IB anything that is a little bit higher level that could influence the navigation of the app or parent containers and stuff.

Q: Have you experimented with CSS type libraries for XCode?

I’ve never tried them, but we did look into markdown. There were some views that had particularly complicated font logic and attributed strings, and if we wanted to use a markdown parser for that. We couldn’t get it as performant as we wanted, and we weren’t in a position where we could adopt it and start contributing back though and just reached a bottleneck. As far as CSS though, we just haven’t had a need.


Check out Patrick’s code samples for this talk on Github


Patrick Reynolds

Patrick Reynolds

Patrick Reynolds is a San Francisco based software engineer who's currently focusing on iOS development while constantly fine-tuning an eye for great product design and user experience. Through working on Adobe's Experience Design team and now at a small startup, he's most engaged when given the opportunity to iterate quickly alongside designers. Outside of his day to day role, he enjoys teaching software development and has worked as a mentor and coach at many local bootcamps.