前语

在2019年的全球开发者大会(WWDC)中,苹果推出了全球果粉最关心的iOS 13操作体系,内置崭新的「暗黑形式」。但是关于大多数开发者来说,在项目创立之后并没有精力来适配,一般手法为直接把暗黑形式封闭。

即:在 Info.plist 文件中,添加 key 为User Interface Style,类型为 String,value 设置为Light即可。

存在即合理,虽然上述装备可以简单粗犷的封闭暗盒形式。但关于夜猫子们来说,并不能带来很友好的体验。So,本文将手把手教育如何办理暗黑形式~

准备思路

实现原理

首要在现已适配的APP傍边,会存在跟从体系高亮形式暗黑形式切换的功用。所以,咱们首要需求创立一个记录用户上一次挑选的状况。关于首次安装的新用户,咱们仅需求默许为跟从体系即可。

这里咱们运用了UserDefaults,是用户默许数据库的接口,一般用于存储用户信息、App 设置等基础信息。在用户切换的时分保存,并且更新全局暗黑or亮堂形式的状况。

最后,咱们需求在用户挑选跟从体系时,获取体系当前的状况。

实现代码

获取发动后APP状况的源码
import SwiftUI
@main
struct MyDarkModelApp: App {
    @StateObject private var appearanceManager = AppearanceManager()
    @Environment(.colorScheme) var colorScheme
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(appearanceManager)
                .preferredColorScheme(appearanceManager.isDarkMode ? .dark : .light)
        }
    }
}
class AppearanceManager: ObservableObject {
    enum AppearanceColor: Int {
        case iSystem = 0
        case iHight = 1
        case iDark = 2
    }
    @Published var isDarkMode: Bool = false
    @Published var type: AppearanceColor {
        didSet{
            switch type {
            case .iSystem:
                isDarkMode = (getCurrentInterfaceStyle() == .dark)
            case .iHight:
                isDarkMode = false
            case .iDark:
                isDarkMode = true
            }
            UserDefaults.standard.set(type.rawValue, forKey: "darkMode")
        }
    }
    init() {
        type = AppearanceColor(rawValue: UserDefaults.standard.integer(forKey: "darkMode")) ?? .iSystem
        switch type {
        case .iSystem:
            isDarkMode = (getCurrentInterfaceStyle() == .dark)
        case .iHight:
            isDarkMode = false
        case .iDark:
            isDarkMode = true
        }
    }
    func getCurrentInterfaceStyle() -> UIUserInterfaceStyle {
        if #available(iOS 13.0, *) {
            return UIScreen.main.traitCollection.userInterfaceStyle
        } else {
            // 在iOS 12或更早的版别中,默许为亮堂形式
            return .light
        }
    }
}
用户切换APP状况并更新的源码
import SwiftUI
struct ContentView: View {
    @EnvironmentObject var appearanceManager: AppearanceManager
    var body: some View {
        VStack() {
            List {
                switch appearanceManager.type {
                case .iSystem:
                    Text("跟从体系")
                case .iHight:
                    Text("淡色形式")
                case .iDark:
                    Text("暗黑形式")
                }
                Text("点我设置亮堂形式").foregroundColor(Color("TextColor")).onTapGesture {
                    appearanceManager.type = .iHight
                }
                Text("点我设置暗黑形式").foregroundColor(Color("TextColor")).onTapGesture {
                    appearanceManager.type = .iDark
                }
                Text("点我设置跟从体系").foregroundColor(Color("TextColor")).onTapGesture {
                    appearanceManager.type = .iSystem
                }
                Image("darkImage")
            }
        }.onAppear {
            print("isDarkMode----->(appearanceManager.isDarkMode)")
        }
    }
}

相关拓展

色彩值、以及图片设置

方法1: 运用 Assets.xcassets 适配深色形式 (图片同理)

项目挑选->Assets.xcassets->右键->New Color Set->设置名称,如图所示:

SwiftUI如何高雅的办理暗黑or高亮形式?

方法2: 运用 extension 适配深色形式 (图片同理)

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)))
  }
}

最终作用

github地址

SwiftUI如何高雅的办理暗黑or高亮形式?