Author | hite, at present in the netease strictly selected iOS group, main work contents webview, spare time to write some thoughts product planning, all kinds of game players clouds

As the biggest new feature of iOS 13, dark mode brings new changes in design system, color, material, system controls, SF Symbols and other aspects from the perspective of designers. For developers, we’re familiar with adaptation;

• Screen size

• Screen orientation

• View rendering (viewDidLoad and viewDidAppear)

• iOS SDK adaptation

Equal fit dimension, and then another dimension,

• Appearance mode (Dark or Light)

For Dark mode adaptation, we need to deal with the logic of images, backgrounds, padding, text and dividers. The first is that designers must design two different color schemes for two kinds of appearance. When the two schemes were delivered to the developers, we also needed to apply different colors according to different looks. Fortunately, developers can create a wrapper that encapsulates this layer of logic and hides the internal logic for other developers to use. For this purpose, iOS provides passive adaptation — dynamic colors;

let backgroundColor = UIColor { (trainCollection) -> UIColor in    if trainCollection.userInterfaceStyle == .dark {        return UIColor.black    } else {        return UIColor.white    }}view.backgroundColor = backgroundColorCopy the code

And active adaptation, we can call in UIViewController or UIView traitCollection. UserInterfaceStyle to obtain the current view of style;

if trainCollection.userInterfaceStyle == .dark {    // Dark} else {    // Light}Copy the code

Or use the Name Assets technology to configure in advance and let the system switch automatically.

In practice, it’s a bit of a hassle. To further simplify the amount of code for adaptation, Apple specifically provides a mechanism called DynamicColorProvider, which has some dynamic colors built in. A “font color” that refers to white in dark mode and black in light mode.

textLabel.textColor = UIColor.labelColorCopy the code

In iOS Design System, text, background and ICONS on the interface are layered with information, and different colors are needed accordingly. Take text colors as an example. IOS 13 has four built-in layers;

• UIColor.labelColor,

• UIColor.secondaryLabelColor,

• UIColor.tertiaryLabelColor,

• UIColor. QuaternaryLabelColor

LabelColor is a primary word color that provides the highest contrast and is used for the most important content elements, such as the main heading of content. And SecondaryLabelColor can be used for subheadings, TertiaryLabelColor for input box placeholder text, and QuaternaryLabelColor for disabled text.

Using dynamic colors is the easiest way to fit dark mode. But it has a problem: what is the color value of labelColor? What’s dark? What’s light?

LabelColor’s answer is simple, but iOS introduces a total of 24 dynamic colors with 48 color values. When it was really merged with our App’s own style system, designers and developers didn’t know that the built-in dynamic color was compatible with the App itself?

When I made the adaptation for 9 Star Browser, my head was too big, I knew the UIColor. SeparatorColor can automatically change color, but whether the color value is in harmony with my App style, there is no color value for me to compare. When I tried to find a complete set of DynamicColor values online, I couldn’t find them for a while. So I’m gonna make my own.

Color matching in Dark mode

color #hex rgba
 labelColor #FFFFFFFF Rgba (255255255,1.00)
 secondaryLabelColor #EBEBF599 Rgba (235235245,0.60)
 tertiaryLabelColor #EBEBF54C Rgba (235235245,0.30)
 quaternaryLabelColor #EBEBF52D Rgba (235235245,0.18)
 linkColor #0984FFFF Rgba (9132255,1.00)
 placeholderTextColor #EBEBF54C Rgba (235235245,0.30)
 separatorColor # 54545899 Rgba (84,84,88,0.60)
 opaqueSeparatorColor #38383AFF Rgba (56,56,58,1.00)
 systemBackgroundColor #000000FF Rgba (0,0,0,1.00)
 secondarySystemBackgroundColor #1C1C1EFF Rgba (28,28,30,1.00)
 tertiarySystemBackgroundColor #2C2C2EFF Rgba (44,44,46,1.00)
 systemGroupedBackgroundColor #000000FF Rgba (0,0,0,1.00)
 secondarySystemGroupedBackgroundColor #1C1C1EFF Rgba (28,28,30,1.00)
 tertiarySystemGroupedBackgroundColor #2C2C2EFF Rgba (44,44,46,1.00)
 systemFillColor #7878805B Rgba (120120128,0.36)
 secondarySystemGroupedBackgroundColor #1C1C1EFF Rgba (28,28,30,1.00)
 tertiarySystemGroupedBackgroundColor #2C2C2EFF Rgba (44,44,46,1.00)
 systemFillColor #7878805B Rgba (120120128,0.36)
 secondarySystemFillColor # 78788051 Rgba (120120128,0.32)
 tertiarySystemFillColor #7676803D Rgba (118118128,0.24)
 quaternarySystemFillColor #7676802D Rgba (118118128,0.18)
 systemRedColor #FF453AFF Rgba (255,69,58,1.00)
 systemGreenColor #30D158FF Rgba (48209,88,1.00)
 systemBlueColor #0A84FFFF Rgba (10132255,1.00)
 systemOrangeColor #FF9F0AFF Rgba (255159,10,1.00)
 systemYellowColor #FFD60AFF Rgba (255214,10,1.00)
 systemPinkColor #FF375FFF Rgba (255,55,95,1.00)
 systemPurpleColor #BF5AF2FF Rgba (191,90,242,1.00)
 systemTealColor #64D2FFFF Rgba (100210255,1.00)
 systemIndigoColor #5E5CE6FF Rgba (94,92,230,1.00)
 systemGrayColor #8E8E93FF Rgba (142142147,1.00)
 systemGray2Color #636366FF Rgba (99,99,102,1.00)
 systemGray3Color #48484AFF Rgba (72,72,74,1.00)

Color matching in light color mode

color #hex rgba
 labelColor #000000FF Rgba (0,0,0,1.00)
 secondaryLabelColor #3C3C4399 Rgba (60,60,67,0.60)
 tertiaryLabelColor #3C3C434C Rgba (60,60,67,0.30)
 quaternaryLabelColor #3C3C432D Rgba (60,60,67,0.18)
 linkColor #007AFFFF Rgba (0122255,1.00)
 placeholderTextColor #3C3C434C Rgba (60,60,67,0.30)
 separatorColor #3C3C4349 Rgba (60,60,67,0.29)
 opaqueSeparatorColor #C6C6C8FF Rgba (198198200,1.00)
 systemBackgroundColor #FFFFFFFF Rgba (255255255,1.00)
 secondarySystemBackgroundColor #F2F2F7FF Rgba (242242247,1.00)
 tertiarySystemBackgroundColor #FFFFFFFF Rgba (255255255,1.00)
 systemGroupedBackgroundColor #F2F2F7FF Rgba (242242247,1.00)
 secondarySystemGroupedBackgroundColor #FFFFFFFF Rgba (255255255,1.00)
 tertiarySystemGroupedBackgroundColor #F2F2F7FF Rgba (242242247,1.00)
 systemFillColor # 78788033 Rgba (120120128,0.20)
 secondarySystemGroupedBackgroundColor #FFFFFFFF Rgba (255255255,1.00)
 tertiarySystemGroupedBackgroundColor #F2F2F7FF Rgba (242242247,1.00)
 systemFillColor # 78788033 Rgba (120120128,0.20)
 secondarySystemFillColor # 78788028 Rgba (120120128,0.16)
 tertiarySystemFillColor #7676801E Rgba (118118128,0.12)
 quaternarySystemFillColor # 74748014 Rgba (116116128,0.08)
 systemRedColor #FF3B30FF Rgba (255,59,48,1.00)
 systemGreenColor #34C759FF Rgba (52199,89,1.00)
 systemBlueColor #007AFFFF Rgba (0122255,1.00)
 systemOrangeColor #FF9500FF Rgba (255149,0,1.00)
 systemYellowColor #FFCC00FF Rgba (255204,0,1.00)
 systemPinkColor #FF2D55FF Rgba (255,45,85,1.00)
 systemPurpleColor #AF52DEFF Rgba (175,82,222,1.00)
 systemTealColor #5AC8FAFF Rgba (90200250,1.00)
 systemIndigoColor #5856D6FF Rgba (88,86,214,1.00)
 systemGrayColor #8E8E93FF Rgba (142142147,1.00)
 systemGray2Color #AEAEB2FF Rgba (174174178,1.00)

From the table above, we have some findings;

• Dynamic colors fall into 3 categories: text colors, used for the most basic information foreground color; Fill color refers to the small area and text to convey information; Large area of background color, these colors are contrast color, auxiliary theme color display, such as tableView background color.

• For text colors, level 4 colors, level 2 to level 4 colors include transparency, but not in the name; SeparatorColor has a clear opaque version of opaqueSeparatorColor;

• Different mode colors of the same color are not opposite values (like labelColor), most colors are fine tones, typically like linkColor. Light color: rgba(0,122,255,255), dark color: rgba(9,132,255,255)

• The color of the systemRedColor series is not affected by the appearance mode.

conclusion

I adapted a version of the 9 Star Browser and the remote keyboard using system dynamic colors, which vaguely felt like something was missing from the previous color scheme, although most of it was similar. Submitted for review at 1 am, lying in bed unable to sleep, feeling unhappy all the time, finally got up, changed all the built-in dynamic colors to custom, and submitted again at 3 am;

# if available (iOS 13.0, *) { let backgroundColor = UIColor { (trainCollection) -> UIColor in if trainCollection.userInterfaceStyle == .light { return UIColor(hex: "#f3f3f3ff")! } else { return UIColor(hex: "#2e2f30ff")! } } tableView.separatorColor = backgroundColor } else { // Fallback on earlier versions tableView.separatorColor = UIColor(hex: "#e3e3e3ff") }Copy the code

Yes, for most apps, you’ll need to deal with both Dark Mode adaptation and iOS version adaptation; Of course, you could write a category or an extension, simplifying this code to

 tableVew.seperatorColor = UIColor(hex: "#e3e3e3ff", darkHex:"#2e2f30ff")Copy the code

Bottom line: Throw out the dynamic colors built into iOS, they’re useless, and the chart above is just to prove how lame dynamic colors are.

Special remind

• Use Any, Dark imageassets for setting custom backButton ICONS in the navigation bar (probably because of my posture), instead

If #available(iOS 13.0, *) { Don't set the back of the tint setting not let on navBarAppearance = UINavigationBarAppearance () navBarAppearance. SetBackIndicatorImage (backImage. transitionMaskImage: backImage) navBarAppearance.titleTextAttributes = [.font: UIFont.systemFont(ofSize: 16, weight: .regular)] navBarAppearance.shadowImage = UIImage() navBarAppearance.shadowColor = .clear navigationController? . The navigationBar. StandardAppearance = navBarAppearance / / change the color of the text and backimage picture let backgroundColor = UIColor { (trainCollection) -> UIColor in if trainCollection.userInterfaceStyle == .light { return UIColor.black } else { return UIColor.white } } navigationController? .navigationBar.tintColor = backgroundColor }Copy the code

• How to enable dark mode. For the main App, as long as the user has dark mode enabled, your App is dark mode; However, for dark mode of remote keyboard and financial keyboard like 9 Star Browser, the host App should also enable dark mode adaptation. For example, the remote keyboard does not have dark mode in wechat, but has dark mode in Safari.

• Change appearance mode in Settings or in Xcode? How does the App respond? For viewControllers, we know that iOS 13 provides a listener

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) if traitCollection.hasDifferentColorAppearance(comparedTo: PreviousTraitCollection) {// adaptation code}}Copy the code

But what about dynamic colors? Such as

text.textColor = UIColor.labelCopy the code

Cause: the system triggered updateDisplay

self.view.setNeedDispay()Copy the code

Trigger. LayoutSubView doesn’t fire, viewDidLoad doesn’t fire.

• Use dark mode with caution, especially if you are using apps that use third-party UI components. They have not been upgraded, and you will encounter strange interfaces when adapting.

• The table above is automatically generated, if you want to add new color values or change the format, you can change it by clicking ColorForDarkMode[3]

reference

[1]https://juejin.cn/post/6844903859739967495; [2]https://www.uisdc.com/ios-13-design [3]https://github.com/hite/ColorForDarkMode [4]https://noahgilmore.com/blog/dark-mode-uicolor-compatibility/


5 interesting iOS libraries
IOS gets an arbitrary thread call stack
Face key points are detected in GPUImage
Fully and deeply parse the URL encoding and decoding process on the iOS terminal