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 在启用时表现不同的主要内容,如果未能解决你的问题,请参考以下文章