Gestalt 2.0.1

Gestalt 2.0.1

测试已测试
语言语言 SwiftSwift
许可 MPL-2.0
发布最后发布2019年7月
SPM支持 SPM

Vincent Esche 维护。



Gestalt 2.0.1

jumbotron

Gestalt

Gestalt 是一个 无侵入式轻量级 的框架,用于应用主题化,支持 动态主题切换

screencast

用法

假设您想为一个带有单个标签的视图控制器设置主题

import Gestalt

struct Theme: Gestalt.Theme {
    let view: ViewTheme = .init()

    static let light: Theme = .init(view: .light)
    static let dark: Theme = .init(view: .dark)
}

struct ViewTheme: Gestalt.Theme {
    let font = UIFont.preferredFont(forTextStyle: .headline)
    let color: UIColor
    let backgroundColor: UIColor

    static let light: Theme = .init(
        color: UIColor.black
        backgroundColor: UIColor.white
    )

    static let dark: Theme = .init(
        color: UIColor.white
        backgroundColor: UIColor.black
    )
}

// In `AppDelegate.application(_:didFinishLaunchingWithOptions:)`
// assign a default theme (or user's choice from user defaults):
ThemeManager.default.theme = Theme.light

class ViewController: UIViewController {
    @IBOutlet var label: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.observe(theme: \Theme.view)
    }
}

extension ViewController: Themeable {

    typealias Theme = ViewTheme

    func apply(theme: Theme) {
        self.view.backgroundColor = theme.backgroundColor
        self.label.textColor = theme.color
        self.label.font = theme.font
    }
}

调用 self.observe(theme: \Theme.view)ThemeManager.default 上为未来的主题更改注册观察者,然后立即调用一次。初始调用不是动画的,但是任何后续更改都是动画的。

要更改当前主题(即使在应用运行时)只需将不同的主题分配给当前使用的 ThemeManager

ThemeManager.default.theme = Theme.dark

这将会导致之前在给定 ThemeManager 上注册的所有闭包再次被调用。

查看 GestaltDemo 目标以获取一个更现实/更复杂的用法示例。

注意

  1. 通常使用 ThemeManager.default 就足够了。然而,也可以通过 let manager = ThemeManager() 创建专门的 ThemeManager

在应用扩展中的应用

在视图已经加载完成之后使用外观代理,这个库使用一种技巧,通过从主窗口中移除并重新添加应用程序的根视图来激活代理。在应用扩展(如图表小工具)中,这是不可能的,因为扩展的安全API限制了对外部主窗口的访问。因此,要在应用扩展中使用此库,您需要手动通过添加以下内容到您根视图控制器中设置主题后触发根视图的重新加载。

ThemeManager.default.observe(theme: Theme.self) { [weak self] _ in
        if let strongSelf = self, let superview = strongSelf.view.superview {
            strongSelf.view.removeFromSuperview()
            superview.addSubview(strongSelf.view)
        }
    }

重要

  1. func apply(theme: Theme) 的实现应该具有 幂等性,以避免在重复调用时的副作用。

安装

Gestalt 添加到项目的推荐方法是使用 Carthage

github 'regexident/Gestalt' ~> 2.0.0

或通过 Cocoapods

pod 'Gestalt', '~> 2.0.0'

或使用 Swift Package Manager

let package = Package(
    name: "GestaltDemo",
    dependencies: [
        .package(url: "https://github.com/regexident/Gestalt.git", from: "2.0.0")
    ],
    targets: [
        .target(name: "GestaltDemo", dependencies: [ "Gestalt" ])
    ]
)

许可证

Gestalt 依据 MPL-2.0 许可证 提供。更多信息请参阅 LICENSE 文件。