在Tab键上编辑NSTableView和NSOutlineView

Dov*_*Dov 6 keyboard macos cocoa nsoutlineview nstableview

我的应用程序有一个NSOutlineView和一个NSTableView,我两个都有同样的问题.如果选择了一行,则按Tab键会将第一列置于编辑模式,而不是使下一个键视图成为第一响应者.要进入下一个关键视图,您需要标记所有列.

此外,切换到任一视图会导致最后一列进入编辑模式,需要更多的shift-tabs才能进入其先前的关键视图.

如果它很重要,我使用自动计算的关键视图循环,而不是我自己的,我的NSWindow设置为autorecalculatesKeyViewLoop = YES.一旦用户选择编辑列,我希望在列之间进行选项卡,但我不认为Tab键触发编辑模式的标准行为.

更新

感谢下面的有用回复,我解决了这个问题.基本上,我-keyDown在我的自定义表视图类中重写,它处理表格视图中的Tab键和shift-tabbing.然而,将换档标签解决到表格视图中更为困难.如果它接受来自另一个视图的控件,我YES在自定义表视图中设置一个布尔属性-acceptsFirstResponder.

代表-tableView:shouldEditTableColumn:row在当前事件是shift-tab keyDown事件时检查该代理.-tableView:shouldEditTableColumn:row被调用并且它不是shift-tab事件,它将表视图的属性设置回来,NO因此它仍然可以像往常一样进行编辑.

我已经粘贴了下面的完整解决方案.

/* CustomTableView.h */

@interface CustomTableView : NSTableView {}

@property (assign) BOOL justFocused;

@end
Run Code Online (Sandbox Code Playgroud)
/* CustomTableView.m */

@implementation CustomTableView

@synthesize justFocused;

- (BOOL)acceptsFirstResponder {
    if ([[self window] firstResponder] != self) {
        justFocused = YES;
    }

    return YES;
}

- (void)keyDown:(NSEvent *)theEvent
{
    // Handle the Tab key
    if ([[theEvent characters] characterAtIndex:0] == NSTabCharacter) {
        if (([theEvent modifierFlags] & NSShiftKeyMask) != NSShiftKeyMask) {
            [[self window] selectKeyViewFollowingView:self];
        } else {
            [[self window] selectKeyViewPrecedingView:self];
        }
    }
    else {
        [super keyDown:theEvent];
    }
}

@end
Run Code Online (Sandbox Code Playgroud)
/* TableViewDelegate.m */

. . .

- (BOOL)tableView:(NSTableView *)tableView shouldEditTableColumn:(NSTableColumn *)tableColumn
              row:(NSInteger)row
{
    NSEvent *event = [NSApp currentEvent];
    BOOL shiftTabbedIn = ([event type] == NSKeyDown
                          && [[event characters] characterAtIndex:0] == NSBackTabCharacter);

    if (shiftTabbedIn && ((CustomTableView *)tableView).justFocused == YES) {
        return NO;
    } else {
        ((CustomTableView *)tableView).justFocused = NO;
    }

    return YES;
}

. . .
Run Code Online (Sandbox Code Playgroud)

Jos*_*ell 7

这是默认行为.如果没有选择行,则表视图整体具有焦点,Tab键切换到下一个键视图.如果选择了行,则表视图开始编辑或移动到下一个单元格(如果已编辑).

来自AppKit发行说明:

表格现在支持小区间导航,如下所示:

  • 向前跳转到表格会聚焦整个表格.
  • 如果该行中只有一个实例,则命中空间将尝试在所选行的NSButtonCell上"performClick:".
  • Tabbing再次聚焦第一个"可聚焦"(1)单元格(如果有的话).
  • 如果可以编辑新聚焦的单元格,则将开始编辑.
  • 命中空间在单元格上调用'performClick:'并在之后设置数据源值(如果已更改).(2)
  • 如果正在编辑文本单元格,则按Enter键将提交编辑,焦点将返回到tableview,Tab/Shift-tab将提交编辑,然后执行新的制表符循环行为.
  • Tabbing只会标记一行
  • 一旦到达连续的最后一个单元格,选项卡将把焦点转移到下一个可聚焦控件.
  • 返回表格将选择最后一个可聚焦单元格.

如果要更改此行为,则委托方法tableView:shouldEditTableColumn:row:可能会有所帮助.NSTableView如果您确实只想影响Tab键的行为,则可能还需要子类化.