我经常以以下方式使用语义颜色来为暗模式和亮模式提供动态颜色。通过这种方法,当用户切换暗/亮模式时,颜色也会在运行时更新:
public static var bw100: UIColor = {
if #available(iOS 13, *) {
return UIColor { (UITraitCollection: UITraitCollection) -> UIColor in
if UITraitCollection.userInterfaceStyle == .dark {
// Return the color for Dark Mode
return .black
} else {
// Return the color for Light Mode
return .white
}
}
} else {
// Return a fallback color for iOS 12 and lower.
return .white
}
}()
现在,我想对Float
值执行相同的操作,例如具有语义上的float var。这意味着我可以为暗模式和亮模式 AND 访问不同的浮点值,如果用户切换暗/亮模式,该值将在运行时适应。我找不到解决方案。
这不起作用,因为它不会在运行时更新。暗/亮模式切换后,必须重新启动该应用程序:
public static var myFloat: Float = {
if #available(iOS 13.0, *) {
if UITraitCollection.current.userInterfaceStyle == .dark {
return 0.9
}
else {
return 0.1
}
}
return 0.1
}()
这也行不通(尝试了与上述工作类似的方法),但是在这里我收到了错误Initializer init(_:) requires that (UITraitCollection) -> Float conforms to BinaryInteger
public static var myFloat: Float = {
if #available(iOS 13, *) {
return Float { (UITraitCollection: UITraitCollection) -> Float in
if UITraitCollection.userInterfaceStyle == .dark {
// Return the Float for Dark Mode
return 0.9
} else {
// Return the Float for Light Mode
return 0.1
}
}
} else {
// Return a fallback for iOS 12 and lower.
return 0.1
}
}()
答案 0 :(得分:1)
这对我实时有效,并且非常接近您所拥有的:
static var myFloat : Float {
let tc = UITraitCollection.current
let mode = tc.userInterfaceStyle
if #available(iOS 13.0, *) {
return (mode == .light ? 1 : 0)
}
return 1
}
正如Leo Dabus指出的那样,您正在做的事情和我正在做的事情之间的唯一真正区别是,我有一个计算所得的属性,每次获取其值时都会重新计算该属性,而您拥有一个定义和调用初始化器,用于初始化后永不更改的属性。
答案 1 :(得分:1)
您无法实现与UIColor
与Float
的工作方式相同的功能,因为UIColor
具有直接用于界面样式更改的特殊初始化程序。但是,解决方案仍然非常简单,正如您所提到的,您必须通过实现traitCollectionDidChange(_:)
来监听界面样式的更改,并手动重新计算数据。
以下代码应为您实现:
// ViewController.swift
var myStoredFloat: Float = 1.0 {
willSet {
print(newValue)
}
}
var myComputedFloat: Float {
let tc = UITraitCollection.current
let mode = tc.userInterfaceStyle
if #available(iOS 13.0, *) {
return (mode == .light ? 1 : 0)
}
return 1
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
self.myStoredFloat = self.myComputedFloat
}
当然,如果您不依赖存储的属性,而只使用计算所得的属性,就可以完全摆脱它。
*感谢亚光获取计算出的属性代码。