0

致力于支持暗模式我已经能够使用这种模式更改主题时更改的动态颜色:

static var dynamicColor: UIColor = {
    if #available(iOS 13, *) {
        return UIColor { (traitCollection: UITraitCollection) -> UIColor in
            switch (traitCollection.userInterfaceStyle, traitCollection.accessibilityContrast) {
            case (.dark, .high):
                return .somethingCustom4

            case (.dark, _):
                return .somethingCustom2

            case (_, .high):
                return .somethingCustom3

            default:
                return .somethingCustom1
            }
        }

    } else {
        return .somethingCustom1
    }
}()

我正在尝试UIColor通过支持暗模式来简化 iOS 12 和 13 之间的创建。我想出了一个简单的Theme枚举来封装上面的所有逻辑,它只公开了 4 种情况,所以上面的声明简化为:

static var customColor: UIColor = {
    switch UIColor.theme {
    case .light:
        return somethingCustom1

    case .dark:
        return .somethingCustom2

    case .lightHighContrast:
        return somethingCustom3

    case .darkHighContrast:
        return .somethingCustom4
    }
}()

问题是,虽然在简化之前所有内容都按应有的方式更新,但现在theme没有获得更新的值,因此颜色不会改变。这就是我Theme使用init(dynamicProvider:)初始化程序声明的方式,但是当您在暗/亮模式之间切换时,它似乎UITraitCollection.current没有正确的值:

public enum Theme {
    case light, dark, lightHighContrast, darkHighContrast

    @available(iOSApplicationExtension 13.0, *)
    init(dynamicProvider: @escaping (UITraitCollection) -> Theme) {
        self = dynamicProvider(UITraitCollection.current)
    }
}

public extension UIColor {
    static var theme: Theme {
        if #available(iOS 13, *) {
            return Theme { (traitCollection: UITraitCollection) -> Theme in
                switch (traitCollection.userInterfaceStyle, traitCollection.accessibilityContrast) {
                case (.dark, .high):
                    return .darkHighContrast

                case (.dark, _):
                    return .dark

                case (_, .high):
                    return .lightHighContrast

                default:
                    return .light
                }
            }

        } else {
            return .light
        }
    }
}

我在这里做错了什么?我认为初始化程序应该是这样工作的,但我无法在网上找到任何其他示例……</p>

4

1 回答 1

0

好的,所以经过大量的混乱之后,我仍然不确定为什么原始实现不起作用,但我确实找到了另一种让它起作用的方法!因此,如果您尝试简化对 iOS 12 和 13 的支持的实现,这就是我最终得到的结果:

public extension UIColor {
    private static func make(dynamicProvider: @escaping (Theme) -> UIColor) -> UIColor {
        guard #available(iOSApplicationExtension 13.0, *) else { return dynamicProvider(.light) }
        return UIColor { (traitCollection) -> UIColor in
            return dynamicProvider(Theme(traitCollection))
        }
    }

    static var customColor: UIColor {
        return .make { (theme) -> UIColor in
            switch theme {
            case .light:
                return .somethingCustom1

            case .dark:
                return .somethingCustom2

            case .lightHighContrast:
                return .somethingCustom3

            case .darkHighContrast:
                return .somethingCustom4
            }
        }
    }
}

public enum Theme {
    case light, dark, lightHighContrast, darkHighContrast

    @available(iOSApplicationExtension 13.0, *)
    init(_ traitCollection: UITraitCollection) {
        switch (traitCollection.userInterfaceStyle, traitCollection.accessibilityContrast) {
        case (.dark, .high):
            self = .darkHighContrast

        case (.dark, _):
            self = .dark

        case (_, .high):
            self = .lightHighContrast

        default:
            self = .light
        }
    }
}
于 2019-10-15T00:14:23.217 回答