Mac Cocoa开发中NSImage切换深浅模式后外观不更新问题
根因说明
NSImage 系统默认会缓存按名称加载的图片资源,缓存内容绑定首次加载时的系统外观,后续切换外观后不会主动失效,因此读取的还是旧缓存的图片。测试时另一张图片因为没有旧缓存,首次加载时会使用当前外观生成对应资源,因此表现正常。
解决方案
- 方案1:加载图片前主动清除对应名称的缓存
修改代码如下即可:
// 先移除旧缓存 NSImage.removeImage(forName: "Image") nsImgaeView.image = NSImage(named: "Image")
- 方案2:强制图片匹配当前视图的有效外观
如果不想清除全局缓存,可以主动指定外观加载对应版本的图片:
guard let rawImage = NSImage(named: "Image") else { return } let targetBounds = nsImgaeView.bounds let currentAppearance = nsImgaeView.effectiveAppearance // 拉取匹配当前外观的图片 representation if let matchingRep = rawImage.bestRepresentation( for: targetBounds, attributes: [.appearance: currentAppearance] ) { let updatedImage = NSImage(size: rawImage.size) updatedImage.addRepresentation(matchingRep) nsImgaeView.image = updatedImage }
- 方案3:监听系统外观变化通知主动刷新
如果担心viewWillLayout触发时机不准确,可以监听外观变化事件单独触发图片刷新:
// 初始化时添加监听 NotificationCenter.default.addObserver( forName: NSAppearance.didChangeNotification, object: nil, queue: .main ) { [weak self] _ in guard let self = self else { return } NSImage.removeImage(forName: "Image") self.nsImgaeView.image = NSImage(named: "Image") }
内容的提问来源于stack exchange,提问作者Wendell
相关产品推荐
相关产品推荐

