关于我:大厂摸鱼 + 业余独立开发,之后会输出深度技术文章 + 独立开发技巧

我的往期技术文章合集:RickeyBoy – Gitbub

我的独立开发 App:iColors – 设计创意 配色助手

iColors 的详细介绍:iColors色彩创意App: 精选配色,图片取色,还有免费四季型人测验!

上一篇内容:独立 App 适配深色形式(二):色彩、图片的适配

⚙️ 第三步:深色形式挑选页面

在 iColors 中,我为 App 内部的深浅形式挑选设置了一个独自的页面,用户能够手动挑选外观是淡色仍是深色,亦或是跟从体系。详细的体现如下图所示:

独立 App 适配深色形式(三):完成挑选页面与大局办理

当然,这一步并不是有必要的。如果本着独立 App 全部从简的思路来说,不要这个设置页面也没问题,适当于是默许给用户一种挑选——跟从体系。体系挑选什么外观,App 内获取到,直接使用就行了。

不过我觉得增加一个设置页面更为便利和灵敏,开发本钱也不大,因而我终究仍是做了这么一个页面。

详细要如何完成呢?首要咱们需求定义一个枚举类型,代表会集不同的外观情况:

enum SchemeType: Int, Identifiable, CaseIterable {
  var id: Self { self }
  case light
  case dark
  case system
 
  /// 获取体系对应的 ColorScheme,用于设置
  var SystemColorScheme: ColorScheme? {
    switch self {
    case .light:
      return .light
    case .dark:
      return .dark
    case .system:
      // 回来 nil 代表不做独自处理
      return nil
    }
  }
}

咱们需求经过 SystemColorScheme,来完成体系的外观类型,和咱们自定义的枚举类型是能够一一对应上的。也便是说现在 SchemeType 是咱们自定义的类型,而 ColorScheme 是体系的类型。

SchemeType.system 代表”跟从体系”,而 ColorScheme == nil 代表没有对外观进行额定的设置,即不做处理。

有了 SchemeType 的类型,下一步咱们就能够便利地写一个挑选页面了:

body {
 ...
 ForEach(SchemeType.allCases) { item in
   SelectionView(...)
 }
}

️ 第四步:大局办理

到现在基本上便是万事俱备只欠东风了,剩余需求做的便是增加大局的环境变量,用作统一办理。咱们依照下面的方法定义一个 ObservableObject 即可:

final class ColorSchemeState : ObservableObject {
  @AppStorage("systemColorSchemeValue") private var currentSchemeValue: Int = SchemeType.system.rawValue
  
  /// App's Selected Color Scheme
  var currentScheme: SchemeType {
    get {
      return SchemeType(rawValue: currentSchemeValue) ?? .system
    }
    set {
      currentSchemeValue = newValue.rawValue
    }
  }
}

这里来稍微解释一下 ColorSchemeState:

  1. 首要咱们经过 @AppStorage 声明了一个变量 currentSchemeValue 来记载外观色彩主题的挑选,同时在 UserDefaults 中同步存储,能够记载用户的挑选。
  2. currentScheme 是揭露的核算属性,提供给外部来获取当时的外观主题
  3. 由于 ColorSchemeState 是一个 ObservableObject,当色彩计划改动时,相关的 UI 能够自动更新

接下来,咱们只需求在 App 初始化时做两件事即可:

  1. 将 colorSchemeState 作为大局环境变量设置进去
  2. 经过 preferredColorScheme 设置默许外观色彩主题
@main
struct XXXApp: App {
 // ... 省掉部分内容
 @StateObject var colorSchemeState = ColorSchemeState()
 
 WindowGroup {
  MainView()
  // ... 省掉部分内容
     .preferredColorScheme(colorSchemeState.currentScheme.SystemColorScheme)
     .environmentObject(colorSchemeState)
 }
}

如果咱们想要在某个详细的页面获取色彩主题信息,甚至于改动外观的挑选,经过这样的方法就行了:

@EnvironmentObject var colorSchemeState: ColorSchemeState
colorSchemeState.currentScheme = ...

这样,咱们整体的大局办理框架就现已搭建完成了!!


至此咱们的深色形式适配就现已全部完结了,大家如果有问题欢迎发问和沟通!