继续创造,加快生长!这是我参与「日新计划 10 月更文挑战」的第1天,点击检查活动概况

大家好,我是 new_cheng

咱们在开发 swiftui 的时分,尽管 swiftui 默许支撑深色形式,关于一些基本的视图,比方文字,布景都有默许的深色形式样式。

可是为了提高用户体验,一般还需要适配深色形式。而关于深色形式的适配,不应在开发完运用后,再去考虑往运用中参加深色形式,应该在开发的初期就做好规划,在开发过程中就能够边开发边测试深色形式的显现作用。

那既然要适配深色形式,在 swiftui 中,咱们该选用什么方法来做呢?

有 2 种常用的的编码方案能够去适配深色形式。

1. UIColor 适配深色形式

能够经过扩展 UIColor 的方法来运用色彩,咱们只需要简单的桥接 UIColor。

extension UIColor {
  convenience init(light: UIColor, dark: UIColor) {
    self.init { traitCollection in
      switch traitCollection.userInterfaceStyle {
      case .light, .unspecified:
        return light
      case .dark:
        return dark
      @unknown default:
        return light
      }
    }
  }
}
extension Color {
  // 再界说一个色彩
  static let defaultBackground = Color(light: .white, dark: .black)
  init(light: Color, dark: Color) {
    self.init(UIColor(light: UIColor(light), dark: UIColor(dark)))
  }
}
// 运用
Text("文字").foregroundColor(Color.defaultBackground)

2. 运用 Assets.xcassets 适配深色形式

Assets.xcassets 允许咱们界说 Color Set,一个 Color Set 包括深色形式和淡色形式所显现的色彩,咱们能够界说多个 Color Set,比方文本,布景,图表等等;经过在 UI 中运用不同的色彩就能完成深色形式的适配,下面来看看详细的操作。

界说 Color Set

在 swiftui 项目挑选 -> Assets.xcassets -> 右键 -> New Color Se -> 设置称号

SwiftUI 开发之旅:适配深色模式

左面的色彩(Any Appearance)默许便是淡色形式显现的色彩,右边如图所示便是深色形式显现的色彩。

挑选色彩,咱们就能够设置色彩的详细色值,Xcode 供给了几种色彩的设置方法,这儿挑选 RGB 即可。

SwiftUI 开发之旅:适配深色模式

在这儿,咱们界说了一个名为 textColor 的 Color Set,下一步咱们会将其运用到代码中。

扩展 Color

为了更便利的运用的咱们界说的色彩集,咱们能够扩展 Color。

创立一个名为 Color.swift 的文件:

import Foundation
import SwiftUI
public extension Color {
  static let textColor = Color("textColor")
}

关于运用 Color 作为参数的修饰符,比方 foregroundColor,background,咱们就能够很便利的直接经过色彩称号来运用:

import SwiftUI
struct DetailHome: View {
    var body: some View {
        Text("姓名").foregroundColor(.textColor)
    }
}

xcode 会供给代码编写提示。

在 xcode 的预览中,将色彩形式设置为 dark appearance,就能检查作用。

SwiftUI 开发之旅:适配深色模式

3. 固定的色彩形式

当咱们不想适配深色形式,咱们能够锁死色彩形式,不论体系当时的设置是深色形式还是淡色形式,咱们都只固定运用某一种色彩形式。

修改项目的 info.plist 文件,添加一条 Appearance 装备,value 为 Dark,App 将会默许运用深色形式,value 为 Light,将会默许运用淡色形式。

SwiftUI 开发之旅:适配深色模式

4. 编码操控深色形式

当你期望在代码中细粒度的操控色彩时,能够经过 colorScheme 环境变量来完成。

import SwiftUI
struct DetailHome: View {
    @Environment(\.colorScheme) var colorScheme: ColorScheme
    var body: some View {
        Text((colorScheme == .dark) ? "暗黑形式" : "淡色形式")
    }
}

SwiftUI 开发之旅:适配深色模式
SwiftUI 开发之旅:适配深色模式

5. 手动切换深色形式

想要让用户手动操控运用的色彩形式,咱们能够供给一个设置页面。

创立一个 AppSetting.swift 文件,用于检测和存储当时运用显现的色彩形式。

这儿咱们用到了 UserDefaults,这是用户默许数据库的接口,一般用于存储用户信息、App 设置等根底信息,但不宜用于存储大量数据。

当用户在体系、深色、淡色3个选项之间切换的时分,咱们会获取到对应的值并赋值darkModeSettings,从而去设置 window.overrideUserInterfaceStyle 来改变运用的色彩形式。

此方法只会影响 window 及其一切子视图和子视图操控器。

import SwiftUI
class AppSetting: ObservableObject {
  @Published var darkModeSettings: Int = UserDefaults.standard.integer(forKey: "darkMode") {
    didSet {
      UserDefaults.standard.set(**self**.darkModeSettings, forKey: "darkMode")
      let scenes = UIApplication.shared.connectedScenes
      let windowScene = scenes.first **as**? UIWindowScene
      let window = windowScene?.windows.first
      switch self.darkModeSettings {
      case 0:
        window?.overrideUserInterfaceStyle = .unspecified
      case 1:
        window?.overrideUserInterfaceStyle = .light
      case 2:
        window?.overrideUserInterfaceStyle = .dark
      default:
        window?.overrideUserInterfaceStyle = .unspecified
      }
    }
  }
}

用户设置深色形式页面:

import SwiftUI
struct MyDarkModel: Identifiable {
  let id: Int
  let image: String
  let name: String
}
struct Test2: View {
  @Environment(\.colorScheme) **var** colorScheme: ColorScheme
  @EnvironmentObject **var** appSettings: AppSetting
 
  let darkModel: [MyDarkModel] = [
    MyDarkModel(id: 0, image: "img_dark_auto", name: "体系"),
    MyDarkModel(id: 1, image: "img_dark_off", name: "淡色"),
    MyDarkModel(id: 2, image: "img_dark_on", name: "深色"),
  ]
  var body: some View {
    VStack() {
      List {
        Section {
          HStack(spacing: 0) {
            ForEach(darkModel) { item in
              Button (action: {
                                // 点击按钮时传递色彩形式的值
                appSettings.darkModeSettings = item.id
              }) {
                if appSettings.darkModeSettings == item.id {
                  Text(item.name)
                    .padding(.horizontal, 24)
                    .padding(.vertical, 12)
                    .foregroundColor(
                                        appSettings.darkModeSettings == item.id?
                                        Color.white :
                                        Color.primary)
                  .background(appSettings.darkModeSettings == item.id ?
                                        Color.blue :
                                        Color.white)
                  .cornerRadius(20)
                } else {
                  Text(item.name)
                    .padding(.horizontal, 24)
                    .padding(.vertical, 12)
                    .foregroundColor(Color.primary)
                }
              }
              .buttonStyle(BorderlessButtonStyle())
              if item.id < 2 {
                Spacer()
              }
            }
          }
          .padding(.horizontal, 4)
          .padding(.vertical)
        }
        Text((colorScheme == .dark) ? "暗黑形式" : "淡色形式")
      }
    }
  }
}
struct Test2_Previews: PreviewProvider {
  static var previews: some View {
    Test2().environmentObject(AppSetting())
  }
}

SwiftUI 开发之旅:适配深色模式
SwiftUI 开发之旅:适配深色模式

总结

经过本文,咱们学会了假如去适配深色形式,把握了 Color Set、overrideUserInterfaceStyle 等运用,还有怎么支撑用户手动切换色彩形式。关于深色形式的适配,推荐选用 Assets.xcassets 的方法去界说一个完整的色彩集来适配。

这是 SwiftUI 开发之旅专栏的文章,是 swiftui 开发学习的经验总结及实用技巧共享,欢迎重视该专栏,会坚持输出。同时欢迎重视我的个人公众号 @JSHub:供给最新的开发信息速报,优质的技术干货推荐。或是检查我的个人博客:Devcursor。

点赞:假如有收获和帮助,请点个赞支撑一下!

收藏:欢迎收藏文章,随时检查!

评论:欢迎评论交流学习,共同进步!