首页 > 其他分享 >Swift中Themeable

Swift中Themeable

时间:2024-10-13 16:21:14浏览次数:6  
标签:themeDidChange applyTheme 主题 func CurrentTheme Swift Themeable

在 Swift 中,Themeable 协议通常用于创建可以根据主题变化而改变外观的对象,比如 UI 组件、视图控制器等。通过实现这个协议,你可以为你的应用提供主题切换的功能,使其在不同的视觉风格下仍然保持一致性。

定义 Themeable 协议

一个简单的 Themeable 协议可能如下所示:

protocol Themeable {
    func applyTheme()
}

实现 Themeable 协议

实现这个协议的对象需要定义 applyTheme() 方法,以便在主题变化时更新其外观。

class ThemedButton: UIButton, Themeable {
    func applyTheme() {
        // 根据当前主题设置按钮的样式
        if CurrentTheme.shared.isDarkMode {
            self.backgroundColor = .black
            self.setTitleColor(.white, for: .normal)
        } else {
            self.backgroundColor = .white
            self.setTitleColor(.black, for: .normal)
        }
    }
}

主题管理

你通常需要一个主题管理器,用于存储和提供当前的主题。可以使用单例模式来实现:

class CurrentTheme {
    static let shared = CurrentTheme()
    
    var isDarkMode: Bool = false {
        didSet {
            notifyThemeChanged()
        }
    }
    
    private init() {}
    
    private func notifyThemeChanged() {
        // 通知所有的 Themeable 对象应用新的主题
        NotificationCenter.default.post(name: .themeDidChange, object: nil)
    }
}

extension Notification.Name {
    static let themeDidChange = Notification.Name("themeDidChange")
}

订阅主题变化

实现了 Themeable 协议的对象可以订阅主题变化的通知,并在主题变化时调用 applyTheme() 方法:

class ViewController: UIViewController, Themeable {
    let button = ThemedButton()

    override func viewDidLoad() {
        super.viewDidLoad()
        // 添加按钮到视图并设置初始主题
        view.addSubview(button)
        applyTheme()
        
        // 订阅主题变化通知
        NotificationCenter.default.addObserver(self, selector: #selector(themeDidChange), name: .themeDidChange, object: nil)
    }
    
    @objc func themeDidChange() {
        applyTheme()
    }

    func applyTheme() {
        // 更新视图控制器的主题
        // 例如更新背景颜色等
        view.backgroundColor = CurrentTheme.shared.isDarkMode ? .black : .white
        button.applyTheme()
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
}

主题切换

可以通过修改 CurrentTheme.shared.isDarkMode 属性来切换主题,从而触发所有订阅者更新其外观。

// 切换主题的示例
CurrentTheme.shared.isDarkMode.toggle()

总结

使用 Themeable 协议可以帮助你实现主题切换的功能,使你的应用在不同的主题下具有一致的外观。通过结合协议、主题管理和观察者模式,你可以创建灵活且可扩展的主题支持系统。

标签:themeDidChange,applyTheme,主题,func,CurrentTheme,Swift,Themeable
From: https://www.cnblogs.com/Tamako-/p/18462516

相关文章

  • swiftformat.yaml字段释义
    swiftformat.yaml文件是用来配置SwiftFormat的格式化规则和选项。以下是各个字段的详细说明:Rules(规则)blankLinesAroundMark:在标记(如#pragmamark)前后添加空行。blankLinesAtEndOfScope:在作用域末尾添加空行。blankLinesAtStartOfScope:在作用域开始处添加空行。......
  • Swift 的 恒等(===)和不恒等(!==)
    Swift提供了两个运算符 === 和 !==,用于判断两个对象是否引用同一个对象实例。这是用来比较引用类型(例如类实例)的操作符,而不是用来比较值类型(如结构体、枚举、基本数据类型)。===:判断两个引用是否指向同一个对象(引用同一块内存地址)。!==:判断两个引用是否指向不同的对象。......
  • SwiftUI 调用相机扫码
    在SwiftUI中调用相机进行扫码(二维码、条形码等),可以通过使用AVCaptureSession和AVCaptureMetadataOutput实现。这可以通过UIViewControllerRepresentable来包装AVCaptureSession,然后与SwiftUI结合。详见代码示例。调用流程创建一个使用AVCaptureSession来处理相......
  • 探索 Swift 中的 withUnsafeBufferPointer 与 Copy-On-Write 机制
    在Swift编程中,对内存管理和性能优化的理解是提高应用效率的关键。今天,我们将深入探讨两个重要主题:使用 withUnsafeBufferPointer 来访问数组的内存地址,以及Swift集合类型(如Array、Dictionary和Set)所采用的Copy-On-Write(COW)机制。withUnsafeBufferPointer 简介with......
  • SwiftUI简明概念(2):renderingMode VS symbolRenderingMode
    一、什么是renderingModeImage的renderingMode可以设置两种值,.original表示渲染图片原来的像素,.template则表示用前景色去渲染图片像素非透明部分,图片只用作形状或者模版。二、什么是symbolRenderingModeImage的symbolRenderingMode可以设置四种值。我们知道SFsymbol可能是......
  • SwiftUI简明概念(1):ForegroundColor VS ForegroundStyle
    一、何谓前景色在SwiftUI体系内,一个View可能包含一个或多个图层,那么最前面的一个图层就是ForegroundColor或ForegroundStyle作用的目标图层。当然这个图层可能不会响应前景色的要求:如上图所示,Rectangle作为shape图层,能响应前景色要求,导致图层变成前景色。Button的作用图层是......
  • Swift查看变量内存地址
    withUnsafePointer不说话,先放代码withUnsafeBufferPointer(to:a){pointinletaddress=UnsafeRawPointer(point)letaddressInt=Int(bitPattern:address)print("\(addressInt)")}验证copyonwrite值......
  • Swift解析json三种方式
    在Swift中解析本地JSON文件有多种形式,以下是其中几种常用的方式:使用Codable协议:使用Codable协议是Swift中解析JSON的推荐方式。首先,你需要定义一个对应的数据模型,该模型需要符合Codable协议。然后使用JSONDecoder对象将JSON数据解析为对应的数据模型对象。......
  • openstack-swift
    对象存储swift对象存储是一种用于存储和管理大量数据的系统。类似于一个超大云盘。可以存储各种文件。(照片,视频,文档等等)。与传统的文件存储不同,对下个存储不关心文件的目录结构和层级关系,而是将每个文件视为一个独立的对象(Object).每个对象都有一个唯一的标识符,我们可以通过这......
  • SwiftData 共享数据库在 App 中的改变无法被 Widgets 感知的原因和解决
    0.问题现象我们watchOS中的App和Widgets共享同一个SwiftData底层数据库,但是在App中对数据库所做的更改并不能被Widgets所感知。换句话说,App更新了数据但在Widgets中却看不到。如上图所示:我们的App在切换至后台之前会随机更新当前的驻场英雄,而驻场英雄......