NSButton mouseDown mouseUp在启用时表现不同

时间:2014-03-13 20:04:05

标签: macos cocoa nsview nsbutton nscontrol

如果未启用NSButton,则mouseDown:和mouseUp:按预期运行(因此,当按下鼠标时,将调用mouseDown:,当它被释放时,将调用mouseUp:)

但是,如果启用了NSButton IS,则完全不会调用mouseUp:并且在鼠标释放后调用mouseDown:

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

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

为什么这种行为会有所不同,以及如何强制执行正确的行为(与未启用按钮时相同)

4 个答案:

答案 0 :(得分:14)

如果有人还在寻找这个......我不知道为什么但这对我有用......

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

答案 1 :(得分:7)

行为是正确的。 所有鼠标向上事件通过响应者方法的期望是错误的。

当启用该按钮时,-mouseDown:的超类实现将运行内部事件跟踪循环以跟踪鼠标移动并将按钮显示为按下,只要鼠标位于其中并显示为未按下当鼠标移出时此内部事件循环是接收NSLeftMouseUp事件的内容。它从未被派遣到响应者方法。

请参阅Cocoa Event Handling Guide: Handling Mouse Events – Handling Mouse Dragging Operations – The Mouse-Tracking Loop Approach

答案 2 :(得分:3)

如果希望创建一个自定义按钮,其操作方法可以区分下载和版本,请尝试将属性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方法。

在操作方法中,可以查询isPressed。 e.g:

int state = (int)[sender isPressed];

令人烦恼但无害的“功能”是释放按钮时调用动作方法两次:NSButtonisPressed仍为真。 (这应该被忽略。)第二次来自自定义按钮的performSelector方法,isPressed为假。

有关这是否可能适用于未来版本的任何评论?

答案 3 :(得分:1)

建立其他人,这是一个Swift与Apple的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
        }
    }