Macos NSButton mouseDown mouseUp在启用时的行为不同

Macos NSButton mouseDown mouseUp在启用时的行为不同,macos,cocoa,nsview,nsbutton,nscontrol,Macos,Cocoa,Nsview,Nsbutton,Nscontrol,如果未启用NSButton,则mouseDown:和mouseUp:的行为与预期一致(因此,当按下鼠标时,将调用mouseDown:,释放鼠标时,将调用mouseUp:) 但是,如果启用了NSButton,则mouseUp:根本不会被调用,而mouseDown:会在释放鼠标后被调用 - (void)mouseDown:(NSEvent *)theEvent { [super mouseDown:theEvent]; } - (void)mouseUp:(NSEvent *)theEve

如果未启用NSButton,则mouseDown:和mouseUp:的行为与预期一致(因此,当按下鼠标时,将调用mouseDown:,释放鼠标时,将调用mouseUp:)

但是,如果启用了NSButton,则mouseUp:根本不会被调用,而mouseDown:会在释放鼠标后被调用

- (void)mouseDown:(NSEvent *)theEvent {
    [super mouseDown:theEvent];
}

- (void)mouseUp:(NSEvent *)theEvent {
    [super mouseUp:theEvent];
}

为什么会有不同的行为,如何强制执行正确的行为(与按钮未启用时相同)行为是正确的。您期望所有鼠标启动事件都通过响应程序方法进行,这是错误的

当按钮被启用时,
-mouseDown:
的超类实现将运行一个内部事件跟踪循环来跟踪鼠标移动,只要鼠标在按钮内,按钮就显示为按下,当鼠标移出时,按钮就显示为未按下。此内部事件循环接收
NSLeftMouseUp
事件。它从未被发送到响应程序方法


请参阅。

如果有人仍在寻找此。。。我不知道为什么,但这对我来说很有用

- (void)mouseDown:(NSEvent *)theEvent {
    NSLog(@"mouse down!");
    [super mouseDown:theEvent];
    NSLog(@"mouse up!");
}

如果希望创建一个自定义按钮,其操作方法可以区分按下和释放,请尝试向其添加属性
isPressed
,并添加以下代码:

 (void)mouseDown:(NSEvent *)event
 {
    self.isPressed = true;  
    [super mouseDown:event];

    self.isPressed = false;

    [self.target performSelector:self.action withObject:self];
}
必须将“自定义”按钮设置为根据发送操作:

[self.button sendActionOn: NSLeftMouseDownMask | NSLeftMouseUpMask];
如果没有此选项,则在释放按钮之前不会调用action方法

在action方法中,可以查询已压缩的
isPressed
。e、 g:

int state = (int)[sender isPressed];
这其中一个恼人但无害的“特性”是,当按钮被释放时,action方法被调用两次:一次从内部
NSButton
,同时
isPressed
仍然为真。(这应该被忽略。)第二次来自自定义按钮的
performSelector
方法,其中
isPressed
false


关于这是否可能在未来的版本中起作用,有什么评论吗?

在其他版本的基础上,这里有一个类似于苹果文档中NSButton子类Objective-C鼠标跟踪循环的快速工作。我们的代码保留事件,而不是将它们传递给超类及其事件循环

override func mouseDown(theEvent: NSEvent) {
    var isInside: Bool = true
    Swift.print( "MyButton Mouse Down" )

    self.highlighted = isInside
    while true {
        let event = self.window?.nextEventMatchingMask(
            Int(NSEventMask.LeftMouseUpMask.union(.LeftMouseDraggedMask).rawValue))
        let mouseLoc = self.convertPoint((event?.locationInWindow)!, toView: nil)
        isInside = CGRectContainsPoint(self.bounds, mouseLoc)
        if event?.type == .LeftMouseDragged {
            self.highlighted = isInside
        }
        else if event?.type == .LeftMouseUp {
            self.highlighted = false
            if isInside {
                Swift.print( "MyButton Mouse Up" )
            }
            break
        }
    }

让我恼火的是,当isEnabled是YES时,不同的行为是肯定的,现在当按钮被禁用时,它就不需要进行内部鼠标跟踪循环。你如何用Swift编写[super mouseDown:theEvent]?我也需要这样做,但在Swift中,我没有在我的override fun mouseDown?中获得mouseDown事件@NealDavis在Swift中您这样编写:
super.mouseDown(theEvent)
如果您希望在释放鼠标单击时实际运行mouseUp功能,这是不正确的。这只是在mouseDown上调用
NSLog(@“mouse up!”)