在视图外部释放鼠标按钮时,NSView不会收到mouseUp:event

MrM*_*age 4 cocoa event-handling nsview appkit mouseup

我有一个自定义NSView子类(例如)以下方法:

override func mouseDown(with event: NSEvent) { Swift.print("mouseDown") }
override func mouseDragged(with event: NSEvent) { Swift.print("mouseDragged") }
override func mouseUp(with event: NSEvent) { Swift.print("mouseUp") }
Run Code Online (Sandbox Code Playgroud)

只要按下鼠标(按钮),拖动并释放所有视图内部​​,这都可以正常工作.但是,当在视图内按下鼠标时,移动到视图外,然后才释放,我从未收到过该mouseUp事件.

PS:调用super实现没有帮助.

MrM*_*age 7

Apple鼠标事件文档的处理鼠标拖动操作部分提供了一个解决方案:显然,我们确实在mouseUp使用鼠标跟踪循环跟踪事件时收到事件.

以下是文档中示例代码的变体,适用于Swift 3:

override func mouseDown(with event: NSEvent) {
    var keepOn = true

    mouseDownImpl(with: event)

    // We need to use a mouse-tracking loop as otherwise mouseUp events are not delivered when the mouse button is
    // released outside the view.
    while true {
        guard let nextEvent = self.window?.nextEvent(matching: [.leftMouseUp, .leftMouseDragged]) else { continue }
        let mouseLocation = self.convert(nextEvent.locationInWindow, from: nil)
        let isInside = self.bounds.contains(mouseLocation)

        switch nextEvent.type {
        case .leftMouseDragged:
            if isInside {
                mouseDraggedImpl(with: nextEvent)
            }

        case .leftMouseUp:
            mouseUpImpl(with: nextEvent)
            return

        default: break
        }
    }
}

func mouseDownImpl(with event: NSEvent) { Swift.print("mouseDown") }
func mouseDraggedImpl(with event: NSEvent) { Swift.print("mouseDragged") }
func mouseUpImpl(with event: NSEvent) { Swift.print("mouseUp") }
Run Code Online (Sandbox Code Playgroud)