我正在使用扩展名和结构中的UIColor和CGColor进行练习。一切正常,但是我意识到如果将来我将添加“主题”功能,如果我从红色更改为蓝色,当更改主题时如何更新所有UIColor和CGColor会怎样?
例如,当我按下按钮更改主题为蓝色时,如何更新所有UIColor / CGColor?
这里是我的代码:
extension UIColor {
public class func dynamicColor(light: UIColor, dark: UIColor) -> UIColor {
return UIColor {
switch $0.userInterfaceStyle {
case .dark: return dark
default: return light
}
}
}
}
var themePick = "Red"
struct AiooColor {
static var tableviewerHeaderTitle: UIColor {
switch themePick {
case "Red": return UIColor.dynamicColor(light: UIColor.systemRed, dark: UIColor.systemRed)
case "Blue": return UIColor.dynamicColor(light: UIColor.systemBlue, dark: UIColor.systemBlue)
// DEFAULT WILL SET TO RED
default: return UIColor.dynamicColor(light: UIColor.systemRed, dark: UIColor.systemRed)
}
}
static var tableviewerHeaderBackground: UIColor {
switch themePick {
case "Red": return UIColor.dynamicColor(light: UIColor(red: 255/255, green: 204/255, blue: 204/255, alpha: 1), dark: UIColor(red: 30/255, green: 0/255, blue: 0/255, alpha: 1))
case "Blue": return UIColor.dynamicColor(light: UIColor(red: 204/255, green: 204/255, blue: 255/255, alpha: 1), dark: UIColor(red: 0/255, green: 0/255, blue: 30/255, alpha: 1))
// DEFAULT WILL SET TO RED
default: return UIColor.dynamicColor(light: UIColor(red: 20/255, green: 0/255, blue: 0/255, alpha: 1), dark: UIColor(red: 20/255, green: 0/255, blue: 0/255, alpha: 1))
}
}
}
说您具有以下结构来跟踪用户首选项键:
struct PreferenceKeys {
static let themeStyle = "theme_style"
}
以及以下枚举(带有原始类型)来描述您的主题样式:
enum ThemeStyle: Int {
case themeA = 0
case themeB
case themeC
case themeD
}
首先,我将创建一个自定义服务来管理您的主题。我们称之为ThemeService。这将允许您存储和检索用户选择的活动主题样式。它可以像这样简单:
protocol ThemeServiceInterface {
func setThemeStyle(_ themeStyle: ThemeStyle)
func getThemeStyle() -> ThemeStyle
}
final class ThemeService: ThemeServiceInterface {
static let shared = ThemeService()
let userDefaults: UserDefaults
private init() {
self.userDefaults = UserDefaults.standard
}
func setThemeStyle(_ themeStyle: ThemeStyle) {
userDefaults.set(themeStyle.rawValue, forKey: PreferenceKeys.themeStyle)
}
func getThemeStyle() -> ThemeStyle {
let rawValue = userDefaults.integer(forKey: PreferenceKeys.themeStyle)
if let themeStyle = ThemeStyle(rawValue: rawValue) {
return themeStyle
}
return .themeA
}
}
因此,当您尝试访问特定颜色时,只需询问主题服务,什么是活动主题样式,并相应地设置颜色。
extension UIColor {
static var primaryColor: UIColor {
switch ThemeService.shared.getThemeStyle() {
case .themeA: return .systemBlue
case .themeB: return .systemRed
case .themeC: return .systemGreen
case .themeD: return .systemIndigo
}
}
static var secondaryColor: UIColor {
.systemPink
}
// ...
}
现在,当用户想要设置新的主题样式时,只需调用以下方法:
ThemeService.shared.setThemeStyle(.themeC)
这很好,您所有新创建的视图都将反映新的主题样式。
但是现在是我们需要为所有现有视图重置UI的部分。好吧,根据项目的结构,您将有不同的选择。
例如,您可以让ThemeService通过NotificationCenter
向所有屏幕发送通知,要求它们重新加载其UI(例如,使用setNeedsDisplay()
/ setNeedsLayout()
方法)
如果这听起来对您的项目来说工作量太大,另一种简便易行的方法可能是简单地用漂亮的动画重置UIWindow的rootViewController
,这将导致您的UI重置并匹配活动主题样式。] >
希望有帮助!