NSButton mouseDown mouseUp 在启用时表现不同

Posted

技术标签:

【中文标题】NSButton mouseDown mouseUp 在启用时表现不同【英文标题】:NSButton mouseDown mouseUp behaving differently on enabled 【发布时间】:2014-03-13 20:04:05 【问题描述】:

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

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

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


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

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

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

如何在 Swift 中编写 [super mouseDown:theEvent]?我需要做同样的事情,但在 Swift 中,我没有在我的覆盖有趣的 mouseDown 中获得 mouseDown 事件? @NealDavis 在 Swift 你这样写:super.mouseDown(theEvent) 如果您想让 mouseUp 功能在释放鼠标时实际运行,这是不正确的。这只是在 mouseDown 上调用 NSLog(@"mouse up!")【参考方案2】:

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

当按钮被启用时,-mouseDown: 的超类实现将运行一个内部事件跟踪循环来跟踪鼠标移动,只要鼠标在按钮内,按钮就会显示为按下,当鼠标在按钮内时显示为未按下。鼠标移出。这个内部事件循环接收NSLeftMouseUp 事件。它永远不会分派给响应者方法。

见Cocoa Event Handling Guide: Handling Mouse Events – Handling Mouse Dragging Operations – The Mouse-Tracking Loop Approach。

【讨论】:

让我烦恼的是 isEnabled 为 YES 和 NO 时的不同行为 当按钮被禁用时,它不需要做内部鼠标跟踪循环。【参考方案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。例如:

int state = (int)[sender isPressed];

其中一个烦人但无害的“功能”是在释放按钮时会调用两次操作方法:一次来自NSButton 内部,isPressed 仍然正确。 (这应该被忽略。)第二次来自自定义按钮的performSelector 方法,isPressed false。

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

【讨论】:

【参考方案4】:

在其他的基础上,这是一个与 Apple 文档中的 NSButton 子类的 Objective-C 鼠标跟踪循环并行工作的 Swift。我们的代码保留了事件,而不是将它们传递给超类及其事件循环。

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
        
    

【讨论】:

以上是关于NSButton mouseDown mouseUp 在启用时表现不同的主要内容,如果未能解决你的问题,请参考以下文章

事件的分类

Cocoa不可变CheckBox

NSButton 值为 1

如何确定 NSButton 是不是为复选框?

Cocoa:当它在NSButton上时更改光标

旋转 NSButton 不起作用