iOS | Dark mode with system colors

Light Mode

Dark Mode

System Colors

For as long as UIKit has existed, it has provided some predefined colors, such as .red, .blue and .yellow, which you could access statically on UIColor.

Now there’s a new palette of colors prefixed with the word system, including .systemRed and .systemBlue.

Semantic Colors

In addition to the newly introduced system colors, iOS 13 also provides semantically defined colors. A semantic color conveys its purpose rather than its appearance or color values.

You don’t have to know these colors’ real raw values. Instead, you use them based on their intention and access them as you would other colors: through static calls on UIColor. Examples of semantic colors include .label, .separator, .link, .systemBackground and .systemFill.

Background Colors

iOS defines two sets of background colors: system and grouped. Each contains primary, secondary and tertiary variants that help you convey a hierarchy of information.

With both sets of background colors, you use the variants to show hierarchy in the following ways:

  • Primary for the overall view.
  • Secondary for grouping content or elements within the overall view.
  • Tertiary for grouping content or elements within secondary elements.

Foreground Colors

For foreground content, such as labels, you can also use various levels of semantic color to convey the importance of the content. Examples of leveled colors include .label, .secondaryLabel, .tertiaryLabel.

Dynamic Colors

While these newly introduced system and semantic colors are useful, they won’t work in all situations. For example, they won’t help you if you need to use brand colors or your design calls for colors other than those Apple provides.

Before Dark Mode, you could incorporate custom colors in several ways. Developers often use code or Asset Catalogs when using UIColor initializers. Fortunately, Apple updated both to take Dark Mode into account.

UITraitCollection

Before continuing, though, you first need to understand the concept of UITraitCollection.

iOS exposes interface environments for any app through the traitCollection property of the UITraitEnvironment protocol. UIWindow, UIViewController and UIView are all classes that conform to this protocol.

UIColor Dynamic Provider

To construct colors in code, you’ll use a closure based initializer.

@available(iOS 13.0, *) public init(dynamicProvider: @escaping (UITraitCollection) -> UIColor)

headerBackgroundView.backgroundColor =
  // 1
  UIColor { traitCollection in
    // 2
    switch traitCollection.userInterfaceStyle {
    case .dark:
      // 3
      return UIColor(white: 0.3, alpha: 1.0)
    default:
      // 4
      return UIColor(white: 0.7, alpha: 1.0)
    }
  }

Asset Catalog

Since iOS 11, you can save your colors in Asset Catalogs and use them both in code and Interface Builder. You can make your colors dynamic with a simple tweak.

Dynamic Images

Open Assets.xcassets. You’ll see two images named hogwarts and hogwarts-night. Click hogwarts.

In the Attributes inspector, click Appearances and choose Any, Dark. A new empty slot appears.

SFSymbols

One of the coolest additions Apple introduced for iOS 13 was SFSympols, a huge set of consistent and highly configurable images. These symbols scale well based on appearance, size and weight. And best of all, you can also use them in your apps for free.

You can download the SF-Symbols mac application in here:
https://devimages-cdn.apple.com/design/resources/download/SF-Symbols-3.2.dmg

houseImageView.image = UIImage(systemName: "house.fill")
houseImageView.tintColor = houseLabel.textColor

SymbolConfiguration:

// Create a configuration object that’s initialized with two palette colors.
var config = UIImage.SymbolConfiguration(paletteColors: [.systemTeal, .systemGray5])

// Apply a configuration that scales to the system font point size of 42.
config = config.applying(UIImage.SymbolConfiguration(font: .systemFont(ofSize: 42.0)))

// Apply the configuration to an image view.
imageView.preferredSymbolConfiguration = config

// Create a symbol image with a tint using UIKit.
imageView.image = image?.withTintColor(.systemRed, renderingMode: .alwaysOriginal)

// Create a new symbol image using the configuration object.
imageView.image = image.applyingSymbolConfiguration(config)

// Create a large scaled symbol image using UIKit.
var config = UIImage.SymbolConfiguration(scale: .large)
imageView.image = image.withSymbolConfiguration(config)

Align Symbol Images with a Text Label by Using a Baseline

NSLayoutConstraint.activate([
    imageView!.firstBaselineAnchor.constraint(equalTo: label!.firstBaselineAnchor)
])

// Create a custom symbol image.
let image = UIImage(named: "custom.multiply.circle")

// Add an offset of 2.0 points from the baseline.
let baselineImage = image?.withBaselineOffset(fromBottom: 2.0)

Turn Dark Mode off

  • Using the UIUserInterfaceStyle key in Info.plist.
  • Set the interface style on the app’s UIWindow, which usually means the whole app.
  • Set the interface style for a specific UIView or UIViewController.

For key window:

var window: UIWindow? {
  didSet {
    window?.overrideUserInterfaceStyle = .light
  }
}

For view controller in viewDidLoad():

overrideUserInterfaceStyle = .light

你可能感兴趣的:(iOS | Dark mode with system colors)