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)
这是默认行为.如果没有选择行,则表视图整体具有焦点,Tab键切换到下一个键视图.如果选择了行,则表视图开始编辑或移动到下一个单元格(如果已编辑).
来自AppKit发行说明:
表格现在支持小区间导航,如下所示:
- 向前跳转到表格会聚焦整个表格.
- 如果该行中只有一个实例,则命中空间将尝试在所选行的NSButtonCell上"performClick:".
- Tabbing再次聚焦第一个"可聚焦"(1)单元格(如果有的话).
- 如果可以编辑新聚焦的单元格,则将开始编辑.
- 命中空间在单元格上调用'performClick:'并在之后设置数据源值(如果已更改).(2)
- 如果正在编辑文本单元格,则按Enter键将提交编辑,焦点将返回到tableview,Tab/Shift-tab将提交编辑,然后执行新的制表符循环行为.
- Tabbing只会标记一行
- 一旦到达连续的最后一个单元格,选项卡将把焦点转移到下一个可聚焦控件.
- 返回表格将选择最后一个可聚焦单元格.
如果要更改此行为,则委托方法tableView:shouldEditTableColumn:row:
可能会有所帮助.NSTableView
如果您确实只想影响Tab键的行为,则可能还需要子类化.