如何通知我的 Cocoa 应用程序 NSScreen 分辨率更改?
How can my Cocoa application be notified of NSScreen resolution changes?
我正在制作一个带有浮动 window 的 Cocoa 应用程序。浮动 window 应该位于主屏幕的中心,大小为主屏幕的 1/4。下面Swift是我申请的精华:
import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
var panel: NSPanel!
func applicationDidFinishLaunching(_ aNotification: Notification) {
let screenRect:CGRect = NSScreen.main()!.frame
panel = NSPanel(
contentRect: NSRect(
x: screenRect.width/4,
y: screenRect.height/4,
width: screenRect.width/2,
height: screenRect.height/2
),
styleMask: NSWindowStyleMask.nonactivatingPanel,
backing: NSBackingStoreType.buffered,
defer: false
)
panel.alphaValue = 0.5
panel.backgroundColor = NSColor.red
panel.level = Int(CGWindowLevelForKey(CGWindowLevelKey.maximumWindow))
panel.orderFront(nil)
}
}
这将生成如下面板:
当主屏幕分辨率改变时出现问题。显示这一点的一种方法是转到“系统偏好设置”>“显示”并将分辨率设置为 "Scaled" 和 "More Space"。这样做之后,面板看起来像这样:
可以看到,更改分辨率后面板的位置不正确。我希望面板保持其位置:居中且为屏幕大小的 1/4。为此,我检测屏幕分辨率(即 NSScreen
的 frame
属性)何时发生变化,以便我可以更改面板的大小和位置。
当 NSScreen
的 frame
属性 发生变化时,是否会触发某些事件?或者有其他方法可以解决这个问题吗?
在@Adolfo 的帮助下,这有效:
import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
var panel: NSPanel!
func getPanelRect() -> NSRect {
let screenRect:CGRect = NSScreen.main()!.frame
return NSRect(
x: screenRect.width/4,
y: screenRect.height/4,
width: screenRect.width/2,
height: screenRect.height/2
)
}
func applicationDidFinishLaunching(_ aNotification: Notification) {
panel = NSPanel(
contentRect: self.getPanelRect(),
styleMask: NSWindowStyleMask.nonactivatingPanel,
backing: NSBackingStoreType.buffered,
defer: false
)
panel.alphaValue = 0.5
panel.backgroundColor = NSColor.red
panel.level = Int(CGWindowLevelForKey(CGWindowLevelKey.maximumWindow))
panel.orderFront(nil)
NotificationCenter.default.addObserver(
forName: NSNotification.Name.NSApplicationDidChangeScreenParameters,
object: NSApplication.shared(),
queue: OperationQueue.main
) { notification -> Void in
print("screen parameters changed")
self.panel.setFrame(self.getPanelRect(), display: true)
}
}
}
我正在制作一个带有浮动 window 的 Cocoa 应用程序。浮动 window 应该位于主屏幕的中心,大小为主屏幕的 1/4。下面Swift是我申请的精华:
import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
var panel: NSPanel!
func applicationDidFinishLaunching(_ aNotification: Notification) {
let screenRect:CGRect = NSScreen.main()!.frame
panel = NSPanel(
contentRect: NSRect(
x: screenRect.width/4,
y: screenRect.height/4,
width: screenRect.width/2,
height: screenRect.height/2
),
styleMask: NSWindowStyleMask.nonactivatingPanel,
backing: NSBackingStoreType.buffered,
defer: false
)
panel.alphaValue = 0.5
panel.backgroundColor = NSColor.red
panel.level = Int(CGWindowLevelForKey(CGWindowLevelKey.maximumWindow))
panel.orderFront(nil)
}
}
这将生成如下面板:
当主屏幕分辨率改变时出现问题。显示这一点的一种方法是转到“系统偏好设置”>“显示”并将分辨率设置为 "Scaled" 和 "More Space"。这样做之后,面板看起来像这样:
可以看到,更改分辨率后面板的位置不正确。我希望面板保持其位置:居中且为屏幕大小的 1/4。为此,我检测屏幕分辨率(即 NSScreen
的 frame
属性)何时发生变化,以便我可以更改面板的大小和位置。
当 NSScreen
的 frame
属性 发生变化时,是否会触发某些事件?或者有其他方法可以解决这个问题吗?
在@Adolfo 的帮助下,这有效:
import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
var panel: NSPanel!
func getPanelRect() -> NSRect {
let screenRect:CGRect = NSScreen.main()!.frame
return NSRect(
x: screenRect.width/4,
y: screenRect.height/4,
width: screenRect.width/2,
height: screenRect.height/2
)
}
func applicationDidFinishLaunching(_ aNotification: Notification) {
panel = NSPanel(
contentRect: self.getPanelRect(),
styleMask: NSWindowStyleMask.nonactivatingPanel,
backing: NSBackingStoreType.buffered,
defer: false
)
panel.alphaValue = 0.5
panel.backgroundColor = NSColor.red
panel.level = Int(CGWindowLevelForKey(CGWindowLevelKey.maximumWindow))
panel.orderFront(nil)
NotificationCenter.default.addObserver(
forName: NSNotification.Name.NSApplicationDidChangeScreenParameters,
object: NSApplication.shared(),
queue: OperationQueue.main
) { notification -> Void in
print("screen parameters changed")
self.panel.setFrame(self.getPanelRect(), display: true)
}
}
}