Dark Mode

Reference links:

WWDC 2019-Implementing Dark Mode on iOS

Reource-Adopting iOS Dark Mode

A, principle

The state UITraitCollection changes the process of passing from screen to view and currently supports manual and automatic triggering. If you set the dynamic color and dynamic image of the view, the color and image of the view will change.

The UITraitEnvironment(iOS 8) protocol method will be called when the current situation changes. For views that need to be individually adapted, the ViewController needs to perform some special processing in this method. UIView and UIViewController comply with this protocol

- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
    [super traitCollectionDidChange:previousTraitCollection];
    
    // Compare the situation change
    BOOL isChanged = [traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection];
}
Copy the code

View layoutSubView, ViewController viewDidLayoutSubviews will trigger traitCollectionDidChange: method

Two, adaptation related

  1. Dynamic Color

    Dynamic color, color switch automatically according to the current situation, 13 new iOS defines a number of dynamic color, most starting with the system, also have begin with applicable categories, for example, labelColor systemGroupedBackgroundColor, You can use it directly

    • Customize dynamic Color

      // iOS 13
      UIColor *dynamicColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull traitC) {
              if (traitC.userInterfaceStyle == UIUserInterfaceStyleDark) {
                  return UIColor.redColor;
              } else {
                  return UIColor.greenColor; }}];Copy the code
    • Take out the color value in the dynamic color according to the current situation —- used to take the color value according to different situations, set the color value.

      UIColor *dynamicColor = [UIColor systemBackgroundColor];
      UITraitCollection *traitCollection = someView.traitCollection;
      UIColor *resolvedColor = [dynamicColor resolvedColorWithTraitCollection:traitCollection];
      Copy the code

      Example Uses:

      		// Set the view border color
      		UILayer *layer = [UILayer new];
      
      		UITraitCollection *traitCollection = someView.traitCollection;
      
      		// option 1 -- iOS 8
      		UIColor *resolvedColor = [dynamicColor resolvedColorWithTraitCollection:traitCollection];
      		layer.borderColor = resolvedColor.CGColor;
      
          // option 2 -- iOS 13
          [traitCollection performAsCurrentTraitCollection:^{
              layer.borderColor = resolvedColor.CGColor;
          }];
          
          // option 3 -- iOS 13
          UITraitCollection *savedTraitCollection = [UITraitCollection currentTraitCollection];
          
          [UITraitCollection setCurrentTraitCollection:traitCollection];
          layer.borderColor = UIColor.labelColor.CGColor;
          
          [UITraitCollection setCurrentTraitCollection:savedTraitCollection];
      Copy the code
  2. Dynamic Image

    • Create a dynamic image

  3. webContent

    • Use color-scheme to declare support
    • Adopt prefers-color-scheme media query
    • Use for hero graphics
    • Consider using var() for color schemes

Examples of front-end code: see WWDC Resource

// color :root {color-scheme: light dark; --post-title-color: #333; --header-bg-color: #593a78; --header-txt-color: white; } @media (prefers-color-scheme: dark) { :root { --post-title-color: white; --header-bg-color: #513d66; --header-txt-color: #eee; } } h1 { color: var(--post-title-color); } .header { background-color: var(--header-bg-color); color: var(--header-txt-color); } // picture <img SRC ="mojave-day.jpg"> <picture> <source srcset="mojave-night.jpg" media=" dark)"> <img src="mojave-day.jpg"> </picture>Copy the code

Three, debugging,

Enable Debug Logging with launch argument

-UITraitCollectionChangeLoggingEnabled YES