Macos 切换暗模式时,NSAppearance未更新
我有一个仅在macOS状态栏中运行的macOS应用程序。我将Info.plist中的“Application is agent(UIElement)”属性更改为“YES”:Macos 切换暗模式时,NSAppearance未更新,macos,macos-big-sur,nsstatusbar,macos-darkmode,Macos,Macos Big Sur,Nsstatusbar,Macos Darkmode,我有一个仅在macOS状态栏中运行的macOS应用程序。我将Info.plist中的“Application is agent(UIElement)”属性更改为“YES”: LSUIElement 我有一个计时器,每5秒打印一次外观名称,如下所示: Timer.scheduledTimer(withTimeInterval:5,repeats:true){in 让外观=NSAppearance.currentDrawing() 打印(外观.名称) } 问题 在“系统设置”中切换“暗/亮”模式
LSUIElement
我有一个计时器,每5秒打印一次外观名称,如下所示:
Timer.scheduledTimer(withTimeInterval:5,repeats:true){in
让外观=NSAppearance.currentDrawing()
打印(外观.名称)
}
问题
在“系统设置”中切换“暗/亮”模式时,名称实际上不会更改。它总是打印应用程序启动时设置的外观名称
有没有办法监听系统外观的变化
目标
我的最终目标实际上是将nsattributed字符串
绘制到NSImage
,并将该NSImage
用作NSStatusItem
按钮的图像
let image:NSImage=//生成图像
statusItem.button?.image=图像
对于属性字符串中的文本,我使用UIColor.labelColor
,它应该基于系统外观。然而,它似乎不尊重系统外观的变化
当我在暗模式下启动应用程序,然后切换到亮模式时:
当我在亮模式下启动应用程序,然后切换到暗模式时:
旁注
我之所以将
NSAttributedString
转换为NSImage
,并且不直接在NSStatusItem
按钮的attributedTitle
上使用NSAttributedString
,是因为。绘制NSAttributedString
的问题是,NSAttributedString
不知道如何渲染动态颜色,例如NSColor.labelColor
。因此,它不会对外观变化做出反应。您必须使用UI元素
解决方案
我通过将nsattributed字符串
传递给NSTextField
并将其绘制到NSImage
中解决了这个问题。很好用
func updateStatusItemImage(){
//使用UI元素:`NSTextField`
让attributedString:NSAttributedString=。。。
设textField=NSTextField(labelWithAttributedString:attributedString)
textField.sizeToFit()
//将'NSTextField'绘制为'NSImage'`
let size=textField.frame.size
让图像=NSImage(大小:大小)
image.lockFocus()
textField.draw(textField.bounds)
image.unlockFocus()
//将绘制的图像指定给“NSStatusItem”的按钮`
statusItem.button?.image=图像
}
对外观变化作出反应
此外,由于NSImage
不知道NSAppearance
我需要通过观察NSStatusItem
按钮的effectiveAppearance
属性来触发外观更改的重绘:
observation=statusItem.observation(\.button?.effectiveAppearance,选项:[]){[weak self]\uuu,\uu在
//重画
self?.updateStatusItemImage()
}
绘制NSAttributedString
的问题是,NSAttributedString
不知道如何渲染动态颜色,例如NSColor.labelColor
。因此,它不会对外观变化做出反应。您必须使用UI元素
解决方案
我通过将nsattributed字符串
传递给NSTextField
并将其绘制到NSImage
中解决了这个问题。很好用
func updateStatusItemImage(){
//使用UI元素:`NSTextField`
让attributedString:NSAttributedString=。。。
设textField=NSTextField(labelWithAttributedString:attributedString)
textField.sizeToFit()
//将'NSTextField'绘制为'NSImage'`
let size=textField.frame.size
让图像=NSImage(大小:大小)
image.lockFocus()
textField.draw(textField.bounds)
image.unlockFocus()
//将绘制的图像指定给“NSStatusItem”的按钮`
statusItem.button?.image=图像
}
对外观变化作出反应
此外,由于NSImage
不知道NSAppearance
我需要通过观察NSStatusItem
按钮的effectiveAppearance
属性来触发外观更改的重绘:
observation=statusItem.observation(\.button?.effectiveAppearance,选项:[]){[weak self]\uuu,\uu在
//重画
self?.updateStatusItemImage()
}