我一直试图解决这个非常令人沮丧的问题,我希望有人可以提供帮助。我正在尝试创建一个有多个视图的NSWindow。视图可以相互重叠。这些是要求。
首次尝试
我试过以下尝试过这个。不幸的是,这根本不起作用。
在NSWindow
override func awakeFromNib() {
self.refreshElements()
self.titlebarAppearsTransparent = true
self.isMovableByWindowBackground = true
}
在我的自定义视图中
class Blue: NSView {
public override var mouseDownCanMoveWindow: Bool { return true }
}
class Yellow: NSView {
public override var mouseDownCanMoveWindow: Bool { return false }
}
第二次尝试
然后我尝试在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)
}
}
我首选的方法是方法3.它是最干净的代码,除了不必要点击然后再次点击以使事情发挥作用之外的其他一切都是完美的。我的问题是,在动态设置为允许移动后,如何强制初始点击也向窗口注册?
答案 0 :(得分:1)
自macOS 10.11起,NSWindow
已为此目的使用方法performDrag(with:)
。它启动窗口拖动就像用户点击并拖动标题栏时所做的那样。您的蓝色视图可以简单地在其覆盖mouseDown()
。
mouseDownCanMoveWindow
的问题在于它只是将问题传递给超级视图。除非所有祖先观看窗口的内容视图都返回true,否则无关紧要。