如何使用 dynamicProvider 为暗模式创建初始化器
How to create an initializer with dynamicProvider for dark mode
致力于支持深色模式,我已经能够使用这种模式让动态颜色随着您更改主题而变化:
static var dynamicColor: UIColor = {
if #available(iOS 13, *) {
return UIColor { (traitCollection: UITraitCollection) -> UIColor in
switch (traitCollection.userInterfaceStyle, traitCollection.accessibilityContrast) {
case (.dark, .high):
return .somethingCustom4
case (.dark, _):
return .somethingCustom2
case (_, .high):
return .somethingCustom3
default:
return .somethingCustom1
}
}
} else {
return .somethingCustom1
}
}()
我正在尝试通过支持暗模式来简化 iOS 12 和 13 之间 UIColor
的创建。我想出了一个简单的 Theme
枚举来封装上面的所有逻辑,它只暴露了 4 个案例,所以上面的声明简化为:
static var customColor: UIColor = {
switch UIColor.theme {
case .light:
return somethingCustom1
case .dark:
return .somethingCustom2
case .lightHighContrast:
return somethingCustom3
case .darkHighContrast:
return .somethingCustom4
}
}()
问题是,虽然在简化之前一切都按预期更新,但现在 theme
没有获得更新的值,所以颜色没有改变。这就是我用 init(dynamicProvider:)
初始化程序声明 Theme
的方式,但是当您在 dark/light 模式之间切换时, UITraitCollection.current
似乎没有正确的值:
public enum Theme {
case light, dark, lightHighContrast, darkHighContrast
@available(iOSApplicationExtension 13.0, *)
init(dynamicProvider: @escaping (UITraitCollection) -> Theme) {
self = dynamicProvider(UITraitCollection.current)
}
}
public extension UIColor {
static var theme: Theme {
if #available(iOS 13, *) {
return Theme { (traitCollection: UITraitCollection) -> Theme in
switch (traitCollection.userInterfaceStyle, traitCollection.accessibilityContrast) {
case (.dark, .high):
return .darkHighContrast
case (.dark, _):
return .dark
case (_, .high):
return .lightHighContrast
default:
return .light
}
}
} else {
return .light
}
}
}
我在这里做错了什么?我认为这就是该初始化程序应该如何工作,但我无法在网上找到任何其他示例……
好吧,经过一番折腾,我仍然不确定为什么原来的实现不起作用,但我确实找到了另一种方法让它起作用!因此,如果您试图简化对 iOS 12 和 13 的支持的实现,这就是我最终得到的结果:
public extension UIColor {
private static func make(dynamicProvider: @escaping (Theme) -> UIColor) -> UIColor {
guard #available(iOSApplicationExtension 13.0, *) else { return dynamicProvider(.light) }
return UIColor { (traitCollection) -> UIColor in
return dynamicProvider(Theme(traitCollection))
}
}
static var customColor: UIColor {
return .make { (theme) -> UIColor in
switch theme {
case .light:
return .somethingCustom1
case .dark:
return .somethingCustom2
case .lightHighContrast:
return .somethingCustom3
case .darkHighContrast:
return .somethingCustom4
}
}
}
}
public enum Theme {
case light, dark, lightHighContrast, darkHighContrast
@available(iOSApplicationExtension 13.0, *)
init(_ traitCollection: UITraitCollection) {
switch (traitCollection.userInterfaceStyle, traitCollection.accessibilityContrast) {
case (.dark, .high):
self = .darkHighContrast
case (.dark, _):
self = .dark
case (_, .high):
self = .lightHighContrast
default:
self = .light
}
}
}
致力于支持深色模式,我已经能够使用这种模式让动态颜色随着您更改主题而变化:
static var dynamicColor: UIColor = {
if #available(iOS 13, *) {
return UIColor { (traitCollection: UITraitCollection) -> UIColor in
switch (traitCollection.userInterfaceStyle, traitCollection.accessibilityContrast) {
case (.dark, .high):
return .somethingCustom4
case (.dark, _):
return .somethingCustom2
case (_, .high):
return .somethingCustom3
default:
return .somethingCustom1
}
}
} else {
return .somethingCustom1
}
}()
我正在尝试通过支持暗模式来简化 iOS 12 和 13 之间 UIColor
的创建。我想出了一个简单的 Theme
枚举来封装上面的所有逻辑,它只暴露了 4 个案例,所以上面的声明简化为:
static var customColor: UIColor = {
switch UIColor.theme {
case .light:
return somethingCustom1
case .dark:
return .somethingCustom2
case .lightHighContrast:
return somethingCustom3
case .darkHighContrast:
return .somethingCustom4
}
}()
问题是,虽然在简化之前一切都按预期更新,但现在 theme
没有获得更新的值,所以颜色没有改变。这就是我用 init(dynamicProvider:)
初始化程序声明 Theme
的方式,但是当您在 dark/light 模式之间切换时, UITraitCollection.current
似乎没有正确的值:
public enum Theme {
case light, dark, lightHighContrast, darkHighContrast
@available(iOSApplicationExtension 13.0, *)
init(dynamicProvider: @escaping (UITraitCollection) -> Theme) {
self = dynamicProvider(UITraitCollection.current)
}
}
public extension UIColor {
static var theme: Theme {
if #available(iOS 13, *) {
return Theme { (traitCollection: UITraitCollection) -> Theme in
switch (traitCollection.userInterfaceStyle, traitCollection.accessibilityContrast) {
case (.dark, .high):
return .darkHighContrast
case (.dark, _):
return .dark
case (_, .high):
return .lightHighContrast
default:
return .light
}
}
} else {
return .light
}
}
}
我在这里做错了什么?我认为这就是该初始化程序应该如何工作,但我无法在网上找到任何其他示例……
好吧,经过一番折腾,我仍然不确定为什么原来的实现不起作用,但我确实找到了另一种方法让它起作用!因此,如果您试图简化对 iOS 12 和 13 的支持的实现,这就是我最终得到的结果:
public extension UIColor {
private static func make(dynamicProvider: @escaping (Theme) -> UIColor) -> UIColor {
guard #available(iOSApplicationExtension 13.0, *) else { return dynamicProvider(.light) }
return UIColor { (traitCollection) -> UIColor in
return dynamicProvider(Theme(traitCollection))
}
}
static var customColor: UIColor {
return .make { (theme) -> UIColor in
switch theme {
case .light:
return .somethingCustom1
case .dark:
return .somethingCustom2
case .lightHighContrast:
return .somethingCustom3
case .darkHighContrast:
return .somethingCustom4
}
}
}
}
public enum Theme {
case light, dark, lightHighContrast, darkHighContrast
@available(iOSApplicationExtension 13.0, *)
init(_ traitCollection: UITraitCollection) {
switch (traitCollection.userInterfaceStyle, traitCollection.accessibilityContrast) {
case (.dark, .high):
self = .darkHighContrast
case (.dark, _):
self = .dark
case (_, .high):
self = .lightHighContrast
default:
self = .light
}
}
}