This talk was given at SwiftConf 2019 which took place in Cologne, Germany on 28-29 August.
Its time to tidy up your styling and layout code!
In this talk, well examine some techniques to get your codebase in shape for dark mode theming, dynamic type support and more - making the app a joy to work with and use.
8. What counts as custom styling?
Settings the text color of a label
Setting the background color of a view
Setting the font descriptor/size of a label
Setting the tint color of a switch
Setting the margins of a view
≒
10. So what?
iOS 13 coming in about 2 weeks
Apple puts the bar pretty high, users have
expectations
You dont want your app to look out of place
Over time suggestions become requirements
15. Hardcoded colors
Quick and visual
Tweaking colors
Find-and-replace can be error prone
One by one easy for small apps
Variations based on traits
For IB use named colors (iOS 11+)
In code there can be a lot of repetitions
17. Color constants
Nice overview of the whole color palette ィ
Tweaking colors
Changing constant value can be error
prone if you don't know how it's used
Requires testing easy for small or
snapshot tested apps
Variations based on traits
All in one place
19. Semantic colors
Allow you to update colors based on their usage
No guarantees what color youre getting
Exactly what we need for Dark Mode and
even High contrast support
Apple moving to them too
Activity indicator white/gray deprecated
New UI Element colors (label, link, separator,
etc)
21. Color themes
Static (at app launch) as a way for a
company to AB test a new color palette
You can already select theme based
on the initial user interface style
Static dark mode > no dark mode
22. Color themes
Dynamic (can change at runtime) as a
way to give users the option to skin
the app
Depends how you have it
implemented
No single system-wide noti鍖cation
If you get the latest theme in
`traitCollectionDidChange(:)` you're
done!
23. Examples
1. High contrast support
2. Dark Mode support
3. Color Constants to Semantic Colors
transition
31. 1. Organize by type, not location
(all colors, not all styles for a screen)
Build a query for all colors used in code
Dont forget .white, .black etc
36. Consolidate things that have the same
purpose & name them accordingly
There will be tricky ones!
Seek a second opinion
You always have the memories and
Git!
4. Iterate
(until you have only things to keep)
37. The Result
Around 10 to 50 different semantic meanings
See examples from Apple, Google, IBM etc
Globally accessible colors in one place
In code or from the asset catalogue
38. Maintainability
Linter rules to ensure colors are being used
Essential, even if there are exceptions
Way more useful if done in collaboration with
designers and for multiple platforms
Brings a set of new problems (single source
of truth, keeping platforms in sync etc)
39. Caveats
No Xcode support for renaming assets
You can use SwiftGen to keep constants in
sync with asset names
Dont know a good solution for Interface
builder
40. Caveats
No Xcode support for renaming assets
You can use SwiftGen to keep constants in
sync with asset names
Dont know a good solution for Interface
builder
Named colors cant reference other named
colors $
47. Other Resources
WordPress iOS wiki: Dynamic type guideline
Five starts blog: iOS Dark mode how to
Use Your Loaf blog:
Supporting dynamic type
Using a custom font with dynamic type
Atimi: iOS dynamic type is important and
about to become more so
55. Preferred Fonts
Can be selected in IB
You dont control the size and weight so
might not meet your needs
Scale but only on initialization (static scaling
fonts)
for scaling while the app is running you
need to con鍖gure it
59. Caveats
Any changes to the font remove the scaling
resizing, changing font traits etc
Scaled font == not scaled font true く
potentially causing a caching bug in
NSAttriutedString
Scaling an already scaled font crashes
64. Metrics
Again, moving away from hardcoded values
Cleaning up systematically + linters
There are APIs that give us default values
layoutMargins, readableContentGuide etc
No corresponding context aware API (yet)
To react on trait collection changes we need to
implement traitCollectionDidChange(:)
66. To make space for new things we often need to
revisit what we have and put it in order 鍖rst.
We can take inspiration from life (& Net鍖ix)
and apply it to the way we approach the
process.
Any of these modernizations is an actual
project with product value and tradeoffs.
Have a conversation with your teams about
how to sparks some joy through your UI!
Wrap up