我有一个基于文档的应用程序。我重写
NSDocument
的 makeWindowControllers
来实例化自定义窗口控制器。它的初始化程序调用其超类的 init(window: NSWindow?)
,即它不使用任何涉及 nib 文件的初始化程序。
如何进行级联工作(参见
shouldCascadeWindows
)?目前,每个窗口都在第一个屏幕上的相同位置打开。
我可以以某种方式重用现有的级联逻辑吗,也许可以通过在
NSWindowController
上调用某些内容?
如果我必须自己手动实现,我应该如何最好地获取最顶层文档窗口的位置?文档的潜在多个窗口中的哪一个应该是计算偏移量的窗口?
func cascadeTopLeft(from topLeftPoint: NSPoint) -> NSPoint
将窗口左上角定位到给定点。
参数
左上角点 窗口的新左上角(在屏幕坐标中)。当 NSZeroPoint 时,窗口不会移动,除非需要约束到可见屏幕
NSZeroPoint
是第一个窗口的起点。
返回值 该点在屏幕坐标中从窗口左上角移动。
讨论
返回的点可以传递给后续调用cascadeTopLeft(from:)来定位下一个窗口,以便两个窗口的标题栏完全可见。
返回的点是下一个窗口的起点。
示例(如文本编辑):
static var cascadingPoint = NSZeroPoint
override func makeWindowControllers() {
let window = NSWindow(contentRect: NSMakeRect(100, 100, 500, 500), styleMask: .titled, backing: .buffered, defer: true)
Document.cascadingPoint = window.cascadeTopLeft(from: Document.cascadingPoint)
let windowController = NSWindowController(window: window)
addWindowController(windowController)
}
另一个例子(如 Safari)
override func makeWindowControllers() {
let window = NSWindow(contentRect: NSMakeRect(100, 100, 500, 500), styleMask: .titled, backing: .buffered, defer: true)
let cascadingPoint = NSApp.mainWindow?.cascadeTopLeft(from: NSZeroPoint) ?? NSZeroPoint
window.cascadeTopLeft(from: cascadingPoint)
let windowController = NSWindowController(window: window)
addWindowController(windowController)
}
我在 Apple 示例项目中发现了这个想法:
创建 NSWindowController 的子类,然后在初始化调用时将实例属性
shouldCascadeWindows
设置为true
。
import Cocoa
class WindowController: NSWindowController, NSWindowDelegate {
override func windowDidLoad() {
super.windowDidLoad()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
/** NSWindows loaded from the storyboard will be cascaded
based on the original frame of the window in the storyboard.
*/
shouldCascadeWindows = true
}
}