内容简介:When Apple introduced the modern and flat design of iOS7 in 2013, many people objected to its user interface’s excessive whiteness. They preferred the more natural-looking materials of previous versions of iOS.In the years leading to up iOS 13, many apps a
When Apple introduced the modern and flat design of iOS7 in 2013, many people objected to its user interface’s excessive whiteness. They preferred the more natural-looking materials of previous versions of iOS.
In the years leading to up iOS 13, many apps added Dark Mode , a new color theme, to compensate for the system’s brightness. This theme helped people use apps in environments with lower light.
Fortunately, in iOS13, Apple decided to grant this feature system-level love. The engineers at Apple added a toggle for users to switch between light and dark appearance. They also updated all pre-installed apps to respect the user’s choice.
Maybe Jony Ive took all the white rooms when he left! Apple decided to embrace the darkness, so why don’t you?
In this tutorial, you’ll add Dark Mode to Dark Arts , an app with information about all the teachers of Defense Against the Dark Arts at Hogwarts.
Specifically, you’ll cover how to:
- Use colors; system, semantic, dynamic, background and foreground.
- Support elevation levels act in dark mode.
- Use different assets in light and dark mode.
- Utilize the power of SF Symbols.
- Opt out of dark mode, should you wish to do so.
- And more..
Getting Started
Download the starter project for this tutorial by clicking the Download Materials button at the top or the bottom of the page. Double-click DarkArts.xcodeproj to open the project in Xcode.
Get familiar with the source code and file structure of the project.
Build and run. You’ll see a list of all the Defense Against the Dark Arts teachers sorted by the year Harry Potter and friends studied with them. Tap any item to see more information.
The app’s user interface is shiny and bright. You’ll remove this as you move through the tutorial.
To see how the app currently looks in Dark Mode, run the app in the simulator and change the interface style as follows.
When you run your app via Xcode, a set of debugging buttons appears at the bottom. Click the Environment Overrides button and a pop-up will appear. There’s an Interface Style toggle at the top of the pop-up.
Now toggle the Interface Style switch and click Dark . The app will look like this:
Not as dark as you hoped, huh? At least the navigation bar background switched to black. But the list stayed white.
System Colors
The most important aspect of adopting a new theme is working with colors. In iOS 13, Apple overhauled colors and introduced a couple of new concepts.
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
. These colors provide suitable and legible shades on both light and dark backgrounds.
Look at this table from Apple Human Interface Guidelines . As you can see, each system color, also known as a tint color, has a different RGB color code for light and dark modes.
Tap Alastor Moody in the app. In the detail screen, the name of the teacher’s Hogwarts house appears in the color of that house’s flag. For example, Alastor Moody is from Hufflepuff so the flag is yellow.
You probably can’t read the house name because the color is the old .yellow
. It wasn’t adapted to look good on light and dark backgrounds, but you’ll soon fix that.
Open TeacherDetailViewController.swift . In viewDidLoad()
, the text color of houseLabel
is set.
Change all the colors to their respective system
variant:
switch teacher.house { case .gryffindor: houseLabel.textColor = .systemRed case .hufflepuff: houseLabel.textColor = .systemYellow case .ravenclaw: houseLabel.textColor = .systemBlue case .slytherin: houseLabel.textColor = .systemGreen }
Build and run. Once again, tap Alastor Moody . Now, you can see he’s from Hufflepuff.
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. Therefore, a semantic color also automatically adapts to Dark Mode.
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.
In general, use the grouped set of background colors when you have a grouped table view. Otherwise, use the system set of background colors.
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.
To see these in action, you’ll now add background colors to the app — this time using a Storyboard.
Open Main.storyboard . In the Dark Arts scene, set the Background for both Table View and TeacherCell to System Background Color .
Build and run to see the effect in both light and dark modes. As you can see, the list’s background color automatically changes based on the appearance, but the texts aren’t visible in Dark Mode.
You’ll fix that next.
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
.
Once again, open Main.storyboard . Then in the Dark Arts scene, set the Color Name Label to Label Color .
Build and run. See the teachers’ names in both light and dark modes.
Pro tip : You can switch the simulator between light and dark mode without going back to Xcode. In the simulator, choose Features ▸ Toggle Appearance — Shift-Command-A — to switch between them.
Nice! With only a few changes, your app is now infinitely better at supporting Dark Mode.
But you can so more!
Elevation
Elevation is the distance between two layers of user interface on the z-axis. In light mode, developers use shadows to enhance depth perception when one layer of user interface is above another.
But that doesn’t work in Dark Mode. While a black drop shadow isn’t visible enough, a lighter shadow for a dark layer doesn’t look right.
To solve this problem, Dark Mode uses two sets of background colors: base and elevated. Base colors are darker, so background interfaces look receded. In contrast, elevated colors are lighter which makes foreground interfaces look protruded.
You can see an excellent example of this concept in action in Modal sheets.
Open Main.storyboard . In Teacher Detail View Controller , set Background for the root View to System Background Color . This is exactly the same value you set for the list background in previous steps.
While you’re here, change the following as well:
- First, set the Color of Name to Label Color .
- Second, set the Color of Taught at Hogwarts to Tertiary Label Color .
- Third, set the Color of Years at Hogwarts to Secondary Label Color .
Build and run. Tap a row to see the details screen.
Look at the background colors of the view controller, which is on the back, and the detail screen, which is in front. Although you set both of them to the same .systemBackgroundColor
, they look different. It’s more obvious in Dark Mode.
Remember, the list in the app had a pure black background in Dark Mode with .systemBackgroundColor
. But in the details screen, when presented as a modal on top of its parent, it has a dark gray background color. This behavior is normal, and given to you without any extra effort.
Dark Mode is dynamic. That means the background color automatically changes from base to elevated when an interface, like a popover or modal sheet, is in the foreground.
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.
You’ll tackle the in-code method first.
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.
You can access many user interface characteristics in an iOS app, such as size classes, force touch capability and style . By taking those properties and related methods into account, you can adapt your user interface to what the system suggests.
Dark Mode is handled under the hood by the magic of trait collections. It’s a new trait, and you’ll learn how to use it next.
UIColor Dynamic Provider
To construct colors in code, you’ll use a closure based initializer.
Open TeacherDetailViewController.swift . Replace this line of code in viewDidLoad()
:
headerBackgroundView.backgroundColor = .white
With this:
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) } }
Here’s a breakdown:
- You call the new initializer of
UIColor
which takes a closure with a single input of typeUITraitCollection
. iOS calls this block and, based on the app’s user interface style, you get a specific color. If the user changes the system interface style, the callback is automatically called again and will change the color accordingly. - You switch on the
userInterfaceStyle
property oftraitCollection
to know what appearance mode the app is in. - If the app is in Dark Mode, it returns a darker shade of gray.
- If the app is not in Dark Mode, it returns a lighter shade of gray.
Build and run. Tap a row to see the header for the detail screen. Then switch to Dark Mode and see the reflected changes.
Creating colors in code is fine if you don’t want to use them in Interface Builder. If you plan on using Interface Builder, you’ll need an Asset Catalog.
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.
Open Assets.xcassets and look at the colors folder. In the Attributes inspector, under the new Appearances section, you can add variations for a color. The simplest option would be Any, Dark , where you provide a new color for the dark appearance. For colors you’ll find a dynamic color named thumbnail-border . It provides a green color for dark mode and a gray color for light mode.
Where are you going to use this color, you ask? You’ll soon see.
Open Main.storyboard . In the Dark Arts scene, there’s a Border View which acts as the stroke around the teachers’ avatars. Currently, its Background is set to a static color: rw-dark . Since you don’t leave the smallest detail behind, change it to thumbnail-border .
Now, build and run. See how the teachers pop even more in Dark Mode.
Dynamic Images
You might have noticed a beautiful painting of Hogwarts at the bottom of the detail page. Wouldn’t it be cool if it showed Hogwarts at night when the app is in Dark Mode?
Great news! You can do that with dynamic images .
Follow the same procedure you used to add a variation to a color in the Asset Catalog for 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.
Right-click hogwarts-night and click Show in Finder . Drag the image from Finder to the empty slot you created in hogwarts . Now delete hogwarts-night since you have both images under the name hogwarts .
Build and run. Enjoy the beautiful moonlight of Hogwarts, but stay away from Lupin.
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.
They’re also Dark Mode ready. You can tint them to any dynamic color, and they adapt beautifully. Unless your app needs specific images and assets, SFSymbols can be your go-to for your illustrations needs.
Time to add some flare to the details screen by adding a house icon beside the house name using SFSymbols.
Open TeacherDetailViewController.swift . In the last line of viewDidLoad()
, add:
houseImageView.image = UIImage(systemName: "house.fill")
This line of code uses the new initializer for UIImage
which takes the name of a symbol in SFSymbols’ catalog.
Build and run. See the beautiful tiny house icon. It’s not as fancy as Hogwarts’ common rooms but, it does the job.
While the house is beautiful in light mode, it’s black and hard to see in Dark Mode. You know how to fix that problem!
Above the line you just inserted, there’s this piece of code which sets the tintColor
of houseImageView
.
houseImageView.tintColor = .black
Replace it with:
houseImageView.tintColor = houseLabel.textColor
This line sets the houseImageView
‘s tintColor
to the textColor
of houseLabel
. Remember, you used system colors for that label so it dynamically adapts to the device appearance.
Build and run. See the home icon now switches color as you switch appearance modes.
Wondering how this happened? It’s the magic of SFSymbols. Remember, they scale well and adapt to your needs. You can use them at any size or color you desire.
and browse the catalog. The string name you used in UIColor’s initializer came from this app.
Opting Out of Dark Mode
Dark Mode is more popular than ever. You can set a device to Dark Mode system-wide, and all Apple and many third-party apps now include it. While you can opt-out of Dark Mode, you might cause eye strain for users who prefer everything in dark. We really encourage you to reconsider before opting out of supporting Dark Mode.
However, if you’re certain you want to opt-out of Dark Mode, you have a few options:
- Turn Dark Mode off for the whole app by 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
orUIViewController
.
You’ll set these for the app one by one.
Note : The final project will stay dark since it breaks the purpose of this tutorial. Also, as you go through each option below, remember to remove the code for opting out of dark mode before trying a new way.
Opting Out with Info.plist
Open Info.plist . Then add a key named UIUserInterfaceStyle and set it to Light .
Build and run the app. Everything shines as if you’d done nothing for Dark Mode.
Remember to remove the above key before continuing to the next step.
Opting Out in UIWindow
Open SceneDelegate.swift . Replace this:
var window: UIWindow?
with:
var window: UIWindow? { didSet { window?.overrideUserInterfaceStyle = .light } }
Since this app uses storyboards, the system sets the window
.
This block of code sets a Swift property observer on window
. As soon as this property is set, you override the interface style to .light
. Since this app only uses a single window, overriding the style on the window causes the app to behave as if you set that key in Info.plist .
Build and run to confirm.
Remember to remove the above code before continuing to the next step.
Opting Out in UIViewController
Open TeacherDetailViewController.swift . You’ll make this view controller a rebel that doesn’t respect Dark Mode.
In viewDidLoad()
, right after the call to super.viewDidLoad()
, insert:
overrideUserInterfaceStyle = .light
This line overrides the style for this specific view controller.
Build and run. Check out the Dark Mode! The list page is dark while the detail page is light.
Where to Go From Here?
You’ve taken a long journey into darkness. Now those Defense Against the Dark Arts teachers have something to battle!
You can download the final project by using the Download Materials button at the top or bottom of this tutorial.
Dark Mode is a simple concept with many smaller parts. To learn more, check out these resources:
- iOS Apprentice by the Ray Wenderlich Tutorial Team
- Dark Mode: Basics Screencast by Rony Rozen
- Dark Mode: Deep Dive Screencast by Rony Rozen
- Ray Wenderlich Forums where you can ask for help from our awesome community.
I hope you enjoyed this tutorial. If you have any questions or comments, please join the discussion below!
以上所述就是小编给大家介绍的《Supporting Dark Mode: Adapting Your App to Support Dark Mode [FREE]》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。