V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
Yunhao
V2EX  ›  分享创造

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

  •  
  •   Yunhao · 2021-01-17 17:36:31 +08:00 · 2101 次点击
    这是一个创建于 1157 天前的主题,其中的信息可能已经有所发展或是发生改变。

    苹果在 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

    2 条回复    2021-01-17 22:04:43 +08:00
    vincentxue
        1
    vincentxue  
       2021-01-17 21:35:04 +08:00
    代码写的不错,如果是非侵入式设计就好了。
    Yunhao
        2
    Yunhao  
    OP
       2021-01-17 22:04:43 +08:00 via iPhone
    @vincentxue 感谢。继续深入学习 Swift,看能不能写的再好一些~
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3501 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 10:52 · PVG 18:52 · LAX 03:52 · JFK 06:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.