在基于视图的表视图中的文本字段中响应鼠标事件 [英] Respond to mouse events in text field in view-based table view

查看:146
本文介绍了在基于视图的表视图中的文本字段中响应鼠标事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在自定义视图内有一个 NSOutlineView 中的文本字段。编辑其中一个单元格需要单击,暂停和单击。第一次单击选择表视图行,第二次单击在字段中绘制光标。双击该单元格,您可以在基于单元格的表视图中进行编辑,只选择该行。

I have text fields inside a custom view inside an NSOutlineView. Editing one of these cells requires a single click, a pause, and another single click. The first single click selects the table view row, and the second single click draws the cursor in the field. Double-clicking the cell, which lets you edit in a cell-based table view, only selects the row.

我想要的行为:单击以更改选择,编辑。

The behavior I want: one click to change the selection and edit.

我需要覆盖以获取此行为?

What do I need to override to obtain this behavior?

  • The NSTextField flyweight pattern wouldn't seem to apply to view-based table views, where the cell views are all instantiated from nibs.
  • I tried subclassing NSTextField like this solution describes, but my overridden mouseDown method is not called. Overridden awakeFromNib and viewWillDraw (mentioned in this post) are called. Of course mouseDown is called if I put the text field somewhere outside a table view.

相比之下,我的单元格视图中的 NSSegmentedControl 在不先选择行的情况下更改其值。

By comparison, a NSSegmentedControl in my cell view changes its value without first selecting the row.

这是从接受的回应修改的工作解决方案

Here's the working solution adapted from the accepted response:

在大纲视图子类:

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

    // Forward the click to the row's cell view
    NSPoint selfPoint = [self convertPoint:theEvent.locationInWindow fromView:nil];
    NSInteger row = [self rowAtPoint:selfPoint];
    if (row>=0) [(CellViewSubclass *)[self viewAtColumn:0 row:row makeIfNecessary:NO]
            mouseDownForTextFields:theEvent];
}

在表格单元格视图子类中:

In table cell view subclass:

// Respond to clicks within text fields only, because other clicks will be duplicates of events passed to mouseDown
- (void)mouseDownForTextFields:(NSEvent *)theEvent {
    // If shift or command are being held, we're selecting rows, so ignore
    if ((NSCommandKeyMask | NSShiftKeyMask) & [theEvent modifierFlags]) return;
    NSPoint selfPoint = [self convertPoint:theEvent.locationInWindow fromView:nil];
    for (NSView *subview in [self subviews])
        if ([subview isKindOfClass:[NSTextField class]])
            if (NSPointInRect(selfPoint, [subview frame]))
                [[self window] makeFirstResponder:subview];
}


推荐答案

偏好 ...子类 NSOutlineView 并覆盖 -mouseDown:,如下所示:

I'll try to return the favor... Subclass NSOutlineView and override -mouseDown: like so:

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

    // Only take effect for double clicks; remove to allow for single clicks
    if (theEvent.clickCount < 2) {
        return;
    }

    // Get the row on which the user clicked
    NSPoint localPoint = [self convertPoint:theEvent.locationInWindow
                                   fromView:nil];
    NSInteger row = [self rowAtPoint:localPoint];

    // If the user didn't click on a row, we're done
    if (row < 0) {
        return;
    }

    // Get the view clicked on
    NSTableCellView *view = [self viewAtColumn:0 row:row makeIfNecessary:NO];

    // If the field can be edited, pop the editor into edit mode
    if (view.textField.isEditable) {
        [[view window] makeFirstResponder:view.textField];
    }
}

这篇关于在基于视图的表视图中的文本字段中响应鼠标事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆