Implement iOS 13 Dark Mode

Dark Mode là chế độ cho phép chuyển giao diện người dùng sang theme màu tối, nhìn khá đẹp, khác biệt với giao diện màu sáng truyền thống và cũng giúp đỡ hại mắt, tiết kiệm pin trên các màn hình OLED...

Apple lần đầu tiên giới thiệu chế độ Dark Mode trên macOS Mojave. Năm nay, tại sự kiện tháng 9 vừa rồi, với sự ra mắt của bộ ba iPhone mới và iOS 13 thì cuối cùng Dark Mode cũng chính thức được Apple support.

Trong macOS Mojave và iOS 13, không phải tất cả các app đều hỗ trợ Dark Mode. Những app này sẽ khiến cho người dùng cảm thấy chúng khá lạc hậu. Và để theo trend "nhà nhà Dark Mode, người người Dark Mode", trong bài viết chúng ta sẽ tìm hiểu cách implement Dark Mode trong iOS 13.

Disable Dark Mode

Để implement Dark Mode, chúng ta cần build project trên Xcode 11.

Giả sử, app của bạn nhìn khá ngon nghẻ khi chạy trên device trước iOS 13 như này:

Tuy nhiên, nếu build app trên Xcode 11 và chạy trên device iOS 13 với chế độ Dark Mode mà không implement gì thêm thì ta có giao diện thay đổi:

Nếu bạn thấy chưa sẵn sàng để implement Dark Mode thì có thể disable nó bằng 2 cách đơn giản sau:

Info.plist

Trong Info.plist, thêm key UIUserInterfaceStyle (Interface Style) và set giá trị này là Light thì app của bạn sẽ luôn hiển thị theme sáng mặc dù đang bật chế độ Dark Mode.

Programmatically

Ngoài cách dùng Info.plist, chúng ta có thể dùng code để disable Dark Mode bằng việc set property overrideUserInterfaceStyle thành .light ở bất kỳ màn hình nào bạn muốn.

Có thể set trên UIView:

Use this property to force the view to always adopt a light or dark interface style. The default value of this property is UIUserInterfaceStyle.unspecified, which causes the view to inherit the interface style from a parent view or view controller. If you assign a different value, the new style applies to the view and all of the subviews owned by the same view controller. (If the view hierarchy contains the root view of an embedded child view controller, the child view controller and its views do not inherit the interface style.) If the view is a UIWindow object, the new style applies to everything in the window, including the root view controller and all presented content.

hoặc UIViewController:

Use this property to force the view controller to always adopt a light or dark interface style. The default value of this property is UIUserInterfaceStyle.unspecified, which causes the view controller to inherit the interface style from the system or a parent view controller. If you assign a different value, the new style applies to the view controller, its entire view hierarchy, and any embedded child view controllers.

Còn nếu bạn muốn disable Dark Mode trên phạm vị toàn bộ app thì đơn giản chỉ cần set cho UIWindow trong AppDelegate như này:

if #available(iOS 13.0, *) {
  window?.overrideUserInterfaceStyle = .light
}

Getting started with Dark Mode

Trước tiên chúng ta cần hiểu một số khái niệm sau:

  • Dark Mode is one of UITraitCollection: UITraitCollection là tập hợp các trait của device như: horizontal, vertical size class, display scale và user interface idiom. Dark mode và light mode là một trait mới của UITraitCollection.

  • Adaptive colors: Thay vì sử dụng các màu sắc cố định, Apple giới thiệu một concept mới về adaptive colors. Nghĩa là với mỗi interface style khác nhau sẽ có màu sắc khác nhau.

  • Adaptive images: Tương tự adaptive colors, đối với mỗi trait dark hay light mode mà sẽ sử dụng ảnh tương ứng phù hợp.

UITraitCollection

Để xác định trait dark hay light trong UITraitCollection, chúng ta có thể dùng property userInterfaceStyle.

Khi người dùng thay đổi dark/light mode, hệ thống sẽ tự động yêu cầu các window và view tự redraw. Trong quá trình này, iOS sẽ call một số method dưới đây để update content của view.

Trước khi call những method này, hệ thống sẽ update trait environment. Vì vậy trong các method này, chúng ta có thể xác định được chính xác các trait thay đổi, từ đó update giao diện.

Adaptive Colors

Apple cung cấp một bộ màu dynamic xây dựng sẵn gọi là System Colors, một set các màu tự động tương thích với light và dark mode.

Hệ thống màu này được chia làm 2 nhóm: tint colors và semantic colors.

System Colors

Tint colors là các màu được định nghĩa sẵn ví dụ như: systemBlue hay systemRed. Khi sử dụng những màu này, tùy theo light hay dark mode mà hệ thống sẽ tự động thay đổi màu blue/red cho phù hợp.

Semantic System Colors

Semantic colors là các màu được design dựa trên mục đích sử dụng, ví dụ: màu cho label, màu cho separator, systemBackground...

Vì vậy, chúng ta không cần biết raw value của các màu này. Và từ iOS 13, chúng cũng sẽ tự động thay đổi để tương thích với dark mode giống như tint colors ở trên.

Chi tiết các màu semantic có thể xem tại UI Element Colors.

Những màu này có thể chọn từ Interface Builder.

Hoặc có thể set bằng code:

view.backgroundColor = .systemBackground
label.color = .label
button.tintColor = .systemBlue

Các màu semantic còn có thể thêm các hiệu ứng vibrancy UIVibrancyEffectStyle và blur UIBlurEffect.Style:

let blur = UIBlurEffect(style: .systemThinMaterial)
let vibrancy = UIVibrancyEffect(blurEffect: blur, style: .label)

Semantic colors chính là nguyên nhân khiến cho app của bạn khi build trên iOS SDK mới (Xcode 11) thì sẽ tự động đổi màu khi chạy trên iOS 13 với dark mode.

Custom Colors

System colors có thể đủ dùng cho hầu hết các trường hợp và Apple cũng recommend sử dụng chúng. Tuy nhiên trong các yêu cầu đặc về UI, chúng ta vẫn phải tự định nghĩa các màu custom và làm chúng trở lên adaptive.

Để làm được điều này, trong asset catalog, khi tạo một Color Set mới, trong phần Attributes inspector, phần Appearances, chúng ta có thể chỉ định các biến thể khác nhau cho các mode: Any, Light, Dark.

Define color in asset catalog like this is backward compatibility, the color you provided in the Any Appearance slots will be used for older versions of macOS or iOS.

Variation Any Appearance sẽ được sử dụng cho các version cũ của macOS và iOS. Còn DarkLight thì tương ứng với dark, light mode.

Adaptive Images

Hầu hết các image đều hiển thị ổn trong cả light mode và dark mode. Nhưng chúng ta vẫn có thể dùng các ảnh khác nhau cho từng mode khác nhau.

Tương tự như Custom Colors, trong asset catalog cũng có các variation cho Appearances.

Testing

Sau khi thực hiện các thay đổi asset, colors, images, khi run app trên simulator, dưới thanh debug, bạn có thể thấy button Environment Overrides.

Button này cho phép thay đổi interface style trong quá trình debug.

Ngoài ra cũng có thể sử dụng Environment Overrides bằng cách dùng menu Debug > View Debugging > Configure Environment Overrides.

Cuối cùng, trong quá trình develop, chúng ta cũng có thể xem các thay đổi trực tiếp trên storyboard bằng cách click View as:... để chuyển qua lại giữa các device size, orientation và interface style.

Conclusion

Chế độ Dark Mode nhìn có vẻ đơn giản chỉ là thay đổi màu sắc . Mặc dù hiện tại Apple không ép buộc tất cả các app phải support Dark Mode nhưng chúng ta nên implement bởi vì việc thay đổi app để support chế độ này không hề khó và tốn quá nhiều thời gian.

Source article: https://sarunw.com/posts/adopting-ios-dark-mode/


All Rights Reserved