mouseDown:在NSTableView中的自定义NSTextField中

mouseDown:在NSTableView中的自定义NSTextField中

问题描述:

我有一个基于视图的NSTableView。表中的每个视图都有一个自定义文本字段。mouseDown:在NSTableView中的自定义NSTextField中

我想在用户点击表格视图内的文本字段(标签)时触发一个动作(想象在每个表格单元格中有一个自定义动作的超链接)。

我创建了一个基本的NSTextField子类来捕获鼠标事件。但是,他们只会触发第二次点击,而不是第一次点击。

我尝试使用NSButton,并立即着火。

这里的自定义标签的代码:

@implementation HyperlinkTextField 

- (void)mouseDown:(NSEvent *)theEvent { 
    NSLog(@"link mouse down"); 
} 

- (void)mouseUp:(NSEvent *)theEvent { 
    NSLog(@"link mouse up"); 
} 

- (BOOL)acceptsFirstResponder { 
    return YES; 
} 

- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent { 
    return YES; 
} 
@end 

原来NSTableViewNSOultineView办理NSTextField情况不同于一个NSButton第一响应状态。

如果我的自定义文本字段类是获取标签以响应第一次单击按钮的关键,那么将覆盖[NSResponder validateProposedFirstResponder:forEvent:]以返回YES

文档:

http://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSResponder_Class/Reference/Reference.html#//apple_ref/occ/instm/NSResponder/validateProposedFirstResponder:forEvent

,你所看到的行为是因为表视图是第一响应者,这应该还是当您单击该行不会改变在标签上 - 这是用户在点击表格行时所期望的行为。我认为将表视图的子类继承并重写mouseDown会更好,而不是继承这个标签。在调用super的实现mouseDown:之后,你可以做一个命中测试来检查用户是否点击了标签。

@implementation CustomTable 

- (void)mouseDown:(NSEvent *)theEvent 
{ 
    [super mouseDown:theEvent]; 
    NSPoint point = [self convertPoint:theEvent.locationInWindow fromView:nil]; 
    NSView *theView = [self hitTest:point]; 
    if ([theView isKindOfClass:[NSTextField class]]) 
    { 
     NSLog(@"%@",[(NSTextField *)theView stringValue]); 
    } 
} 

@end 
+0

谢谢,我会尝试。一个问题:第一次点击与NSButton一起工作(在这种情况下表格行未被选中)。有什么办法模仿这种行为? – Mark 2012-03-24 08:52:41

+0

可能有,但我不知道。我原以为acceptFirstMouse和/或accepFirstResponder返回YES是可以做到的。 – rdelmar 2012-03-24 15:49:45

+0

如果您想要使用按钮获得的行为,为什么不使用按钮?您可以关闭边框,无论如何它看起来都像无边界标签。如果你想要一个边框,你可以在NSBox中嵌入一个无边界按钮。 – rdelmar 2012-03-24 16:06:33

有同样的问题。这里接受的答案不适合我。经过很多努力之后,当我选择“无”作为默认的“常规”时,奇迹般地工作,另一个选项是IB列表视图的“高亮”选项的“源列表”。

编辑:接受的答案被证明是误导性的,因为该方法是重载的表视图,而不是文本字段的答案建议。它在https://stackoverflow.com/a/13579469/804616更清楚地给出,但无论如何,更具体的感觉有点hacky。

+0

这不起作用。也许你做了别的什么 – 2015-02-26 16:36:54

+2

它似乎确实有效。我试图触发mouseUp,但这不适用于任何方法。 MouseDown与 – 2015-02-26 22:10:37

+0

一起工作虽然这确实起作用,但如果您希望表视图使用源列表表视图样式呢? – 2018-01-18 10:54:04

在完全相同的情况下,嵌入NSButtontransparent设置为true/YES为我工作。

class LinkButton: NSTextField { 

    var clickableButton:NSButton? 

    override func viewDidMoveToSuperview() {    
     let button = NSButton() 
     self.addSubview(button) 

     //setting constraints to cover the whole textfield area (I'm making use of SnapKit here, you should add the constraints your way or use frames 
     button.snp_makeConstraints { (make) -> Void in 
      make.edges.equalTo(NSEdgeInsetsZero) 
     } 
     button.target = self 
     button.action = Selector("pressed:") 
     button.transparent = true 
    } 

    func pressed(sender:AnyObject) { 
     print("pressed") 
    } 

使用window.makeFirstResponser(myTextfield)开始编辑文本字段。你从重写mouseDown(withEvent TheEvent:NSEvent)方法发送此消息方法