【问题标题】:Swift update UIColor when change color更改颜色时 Swift 更新 UIColor
【发布时间】:2020-10-04 09:23:02
【问题描述】:

我正在使用扩展和结构中的 UIColor 和 CGColor 进行练习。一切正常,但我意识到如果将来我将添加“主题”功能,如果我从红色更改为蓝色,我如何在更改主题时更新所有 UIColor 和 CGColor?

例如,当我按下按钮将主题更改为蓝色时,它如何更新所有 UIColor / CGColor?

这是我的代码:

extension UIColor {
    public class func dynamicColor(light: UIColor, dark: UIColor) -> UIColor {
        return UIColor {
            switch $0.userInterfaceStyle {
            case .dark: return dark
            default: return light
            }
        }
    }
}

var themePick = "Red"
struct AiooColor {
    static var tableviewerHeaderTitle: UIColor {
        switch themePick {
        case "Red": return UIColor.dynamicColor(light: UIColor.systemRed, dark: UIColor.systemRed)
        case "Blue": return UIColor.dynamicColor(light: UIColor.systemBlue, dark: UIColor.systemBlue)
        // DEFAULT WILL SET TO RED
        default: return UIColor.dynamicColor(light: UIColor.systemRed, dark: UIColor.systemRed)
        }
    }

    static var tableviewerHeaderBackground: UIColor {
        switch themePick {
        case "Red": return UIColor.dynamicColor(light: UIColor(red: 255/255, green: 204/255, blue: 204/255, alpha: 1), dark: UIColor(red: 30/255, green: 0/255, blue: 0/255, alpha: 1))
        case "Blue": return UIColor.dynamicColor(light: UIColor(red: 204/255, green: 204/255, blue: 255/255, alpha: 1), dark: UIColor(red: 0/255, green: 0/255, blue: 30/255, alpha: 1))
        // DEFAULT WILL SET TO RED
        default: return UIColor.dynamicColor(light: UIColor(red: 20/255, green: 0/255, blue: 0/255, alpha: 1), dark: UIColor(red: 20/255, green: 0/255, blue: 0/255, alpha: 1))
        }
    }
}

【问题讨论】:

    标签: ios swift static uicolor cgcolor


    【解决方案1】:

    假设您有以下结构来跟踪用户首选项键:

    struct PreferenceKeys {
        static let themeStyle = "theme_style"
    }
    

    以及以下枚举(带有原始类型)来描述您的主题风格:

    enum ThemeStyle: Int {
        case themeA = 0
        case themeB
        case themeC
        case themeD
    }
    

    首先,我将创建一个自定义服务来管理您的主题。我们称之为 ThemeService。这将允许您存储和检索用户选择的活动主题样式。可以这么简单:

    protocol ThemeServiceInterface {
        func setThemeStyle(_ themeStyle: ThemeStyle)
        func getThemeStyle() -> ThemeStyle
    }
    
    final class ThemeService: ThemeServiceInterface {
    
        static let shared = ThemeService()
    
        let userDefaults: UserDefaults
    
        private init() {
            self.userDefaults = UserDefaults.standard
        }
    
        func setThemeStyle(_ themeStyle: ThemeStyle) {
            userDefaults.set(themeStyle.rawValue, forKey: PreferenceKeys.themeStyle)
        }
    
        func getThemeStyle() -> ThemeStyle {
            let rawValue = userDefaults.integer(forKey: PreferenceKeys.themeStyle)
            if let themeStyle = ThemeStyle(rawValue: rawValue) {
                return themeStyle
            }
            return .themeA
        }
    }
    

    因此,当您尝试访问特定颜色时,只需询问您的主题服务什么是活动主题样式,并相应地设置您的颜色。

    extension UIColor {
    
        static var primaryColor: UIColor {
            switch ThemeService.shared.getThemeStyle() {
            case .themeA: return .systemBlue
            case .themeB: return .systemRed
            case .themeC: return .systemGreen
            case .themeD: return .systemIndigo
            }
        }
    
        static var secondaryColor: UIColor {
            .systemPink
        }
    
        // ...
    }
    

    现在当您的用户想要设置新的主题样式时,您只需调用以下方法:

    ThemeService.shared.setThemeStyle(.themeC)
    

    这太棒了,您新创建的所有视图都将反映新的主题风格。

    但是现在我们需要为所有现有视图重置 UI。嗯,根据你的项目结构,你会有不同的选择。

    例如,您可以让 ThemeService 通过 NotificationCenter 向所有屏幕发送通知,要求他们重新加载 UI(例如使用 setNeedsDisplay() / setNeedsLayout() 方法)

    如果这听起来对您的项目来说工作量太大,另一种简单的好方法可能是简单地重置 UIWindow 的 rootViewController 并使用漂亮的动画,这将导致您的 UI 被重置并匹配活动主题样式。

    希望对你有帮助!

    【讨论】:

    • 这是专业设置主题的完美例子,我从你那里学到了新东西!但只有一件事让我感到困惑,当我单击按钮时,我可以看到打印说主题已更改为蓝色主题,但不会重置 UI。你能告诉我如何重置用户界面的例子吗?喜欢在设置主题后调用所有 UIColor 或 CGColor 来重置?我尝试使用 SetNeedsDisplay() 和 SetNeedsLayout() 但不起作用
    • 等等,刚刚收到!!!你太棒了,谢谢你!!!
    • 不客气!我很高兴你能设法让它工作:)
    • 啊,还有一个……刚刚发现……老实说,您的代码可以完美运行!但是由于我有 UITabBarController - 当我单击按钮时,颜色会更新所有内容,但是当我切换选项卡时(比如我有三个选项卡,主页、提醒、设置),颜色没有更新。例如,当我在主页选项卡中更改时,它会变为蓝色,但是当我单击提醒时,一切都是红色的。好像不能在其他 ViewController 中更新颜色??
    猜你喜欢
    • 2019-12-07
    • 2020-08-29
    • 2014-12-23
    • 2020-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多