苹果在 iOS 13 推出了 Dark Mode,可以让 iOS App 拥有 Light 和 Dark 两套主题。但是,如果你的 App 需要支持更多主题切换,可以试一试 Crystal,一个轻量、简洁的 iOS 主题管理库。
https://github.com/yunhao/Crystal
如果你对这个库感兴趣,欢迎 Star 。
你可以使用 class,struct 甚至 enum 来定义你的 Theme,然后可以在项目的某个地方集中管理这些主题:
// 定义主题类型。
public struct AppTheme {
var textColor: UIColor
var backgroundColor: UIColor
}
// 实例化主题,一个主题就是一个对象。
extension AppTheme {
static var light: AppTheme {
return AppTheme(textColor: .black, backgroundColor: .white)
}
static var sunny: AppTheme {
return AppTheme(textColor: .yellow, backgroundColor: .white)
}
// ... 更多主题
}
extension AppTheme: CrystalThemeType {
// 返回 app 启动时的初始主题。
public static var entry: CrystalThemeType { Self.light }
}
主题不需要 Hard-coding 。结合 Swift Codable 协议,你还可以读取本地文件、从网络请求 JSON,然后动态加载主题。
所有由库引入的扩展方法都暴露在目标对象的 .cst
属性下,无其他额外属性引入,不会污染目标对象。
你只需要把主题的值赋予目标对象上,就像在 UIKit 中经常做的那样。即使之后增加、删除主题,这部分代码也不需要修改!
// 为按钮设置主题。
doneButton.cst.apply { button, theme in
button.setTitleColor(theme.textColor, for: .normal)
}
// 自定义 view 。
cardView.cst.apply { card, theme in
card.backgroundColor = theme.backgroundColor
card.someTextColor = theme.textColor
}
// Swift 简写。
imageView.cst.apply { $0.tintColor = $1.textColor }
// 切换主题
Crystal.shared.theme = .sunny
// 或者,加一个动画
UIView.animate {
Crystal.shared.theme = .light
}
// 添加一个新的主题
extension AppTheme {
static var summer: AppTheme {
return AppTheme(textColor: .red, backgroundColor: .white)
}
}
Crystal.shared.theme = .summer
// 你可以直接设置一个新的主题。
Crystal.shared.theme = AppTheme(textColor: .red, backgroundColor: .white)
为了不过于冗长,这里省略了部分代码,欢迎到项目主页查看 README 。
Crystal 使用 Weak Key Dictionary 来管理这些对象和闭包,在必要时自动释放以防止内存泄漏,具体实现可参考源码。
1
vincentxue 2021-01-17 21:35:04 +08:00
代码写的不错,如果是非侵入式设计就好了。
|
2
Yunhao OP @vincentxue 感谢。继续深入学习 Swift,看能不能写的再好一些~
|