一个 Swift 编写,轻量简洁的 iOS 主题管理库

2021-01-17 17:36:31 +08:00
 Yunhao

苹果在 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 来管理这些对象和闭包,在必要时自动释放以防止内存泄漏,具体实现可参考源码。

项目地址: https://github.com/yunhao/Crystal

2147 次点击
所在节点    分享创造
2 条回复
vincentxue
2021-01-17 21:35:04 +08:00
代码写的不错,如果是非侵入式设计就好了。
Yunhao
2021-01-17 22:04:43 +08:00
@vincentxue 感谢。继续深入学习 Swift,看能不能写的再好一些~

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/745675

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX