So I've posted on Apple Developer Forums, but haven't gotten a reply yet.
Background:
iOS 13 has introduced Dark Mode and a number of System Colors with predefined Light and Dark variants: (https://developer.apple.com/videos/play/wwdc2019/214/)
These colors can be used in the storyboard directly as named colors. They've also been added as static colors to the UIColor class: (https://developer.apple.com/documentation/uikit/uicolor/ui_element_colors)
However, static colors added to UIColor are not available in code in iOS 11 and 12. This makes its tricky to use them as all references to the new System Colors must be wrapped in an availability check:
It also raises the question: on iOS 11 and 12, what will the System colors resolve to when used directly in the Storyboard? In our testing they seem to resolve to the Light variant, though we haven't tested all of them.
Current approach:
This is the approach we are leaning towards. We will add all colors to our Colors.xcassets file for older iOS version support, and through our CustomColors Enum perform a single version check and mapping so the correct UIColor system colors is returned depending on the iOS version. Once we drop support for iOS 11 and 12 we will remove the respective colors from Colors.xcassets as we will only be using the System Colors instead. We will also refactor all our storyboards to use the new System Colors.
The drawbacks of this approach are:
- If we want to use system colors directly in our code after we drop support for iOS 11 and 12 (UIColor.label, UIColor.systemBackground, etc), it could be quite a large refactor to get rid of all the enum references
- Because we will be using System Colors in our storyboard, we must ensure that our Colors.xcassets equivalents use the same color code
- This bug: (UIColor(named:) always returns nil on iOS 11.0-11.2) - if its not fixed then this approach is unusable (EDIT: This bug is fixed in XCode 11 GM seed 2 11A420a)
- As with all Asset Catalogs, using magic strings to access items in the catalog makes it easy for developers to make a mistake and get nil instead of the asset (the color in this case). This could result in difficult-to-pick-up bugs if we don't test every single screen, forcing us to write the crashIfAllColorsNotDefined() method. using an enum does mitigate this risk as the magic strings are only stored/used in one place.
Other approaches: (How do I easily support light and dark mode with a custom color used in my app?)
Question:
What are some other approaches one could use to support Dark Mode with iOS 13 by using the new System colors, while still supporting iOS 11 and 12? And is it safe to use the new System Colors in Storyboards on older iOS versions?