我一直在努力解决这个非常令人沮丧的问题,希望有人能提供帮助。我正在尝试创建一个具有多个视图的 NSWindow。视图可以相互重叠。这些就是要求。
第一次尝试
我已经通过尝试以下方法进行了尝试。不幸的是,这根本行不通。
在 NSWindow 中
override func awakeFromNib() {
self.refreshElements()
self.titlebarAppearsTransparent = true
self.isMovableByWindowBackground = true
}
Run Code Online (Sandbox Code Playgroud)
在我的自定义视图中
class Blue: NSView {
public override var mouseDownCanMoveWindow: Bool { return true }
}
class Yellow: NSView {
public override var mouseDownCanMoveWindow: Bool { return false }
}
Run Code Online (Sandbox Code Playgroud)
第二次尝试
然后我尝试在 Blue 中实现mouseDown mouseDragged和。mouseUp我会计算鼠标self.setFrame(frameRect:display:animate:)在窗口上的移动。这很有效,因为我可以控制移动窗口,但它有几个问题。无论如何,窗口的移动速度总是较慢。我认为即使我将animate属性设置为 false,它也会有动画。而且它不像其他窗口那样激活 Expose。
第三次尝试
这是我在一个重大问题上最接近我想要的行为。初始 mouseDown 未注册。所以你不能点击蓝色视图并拖动和移动窗口。您可以使用 mouseDown、mouseUp,然后再次使用 mouseDown,以便通过拖动来移动窗口。
public class MyWindow: NSWindow {
@IBOutlet var blue: NSView!
@IBOutlet var yellow: NSView!
public override func awakeFromNib() {
self.titlebarAppearsTransparent = true
self.isMovable = false
self.isMovableByWindowBackground = true
}
public override func mouseDown(with event: NSEvent) {
let point = event.locationInWindow
let move = NSPointInRect(point, self.blue.frame)
self.isMovableByWindowBackground = move
self.isMovable = move
super.mouseDown(with: event)
}
public override func mouseDragged(with event: NSEvent) {
super.mouseDragged(with: event)
}
}
Run Code Online (Sandbox Code Playgroud)
我首选的方法是方法 3。它是最干净的代码,除了必须单击然后再次单击才能正常工作的异常行为之外,其他一切都很完美。我的问题是,在动态设置为允许移动后,如何强制初始单击也注册到窗口?
从 macOS 10.11 开始,就有了用于此目的的NSWindow方法。performDrag(with:)它启动窗口拖动,就像用户单击并拖动标题栏时所做的那样。您的蓝色视图可以简单地在其覆盖中调用它mouseDown()。
问题mouseDownCanMoveWindow是它只是将问题传递给超级视图。除非直到窗口内容视图的所有祖先视图都返回 true,否则这并不重要。