How to forward events up / down keyboard from NSTextField to NSTableView?

I'm trying to simulate how Spotlight works in Yosemite, where an NSTextField (search field) always keeps focus when you press the up / down arrow keys and moves the table selection up and down.

I implemented the following code:

- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector { if (commandSelector == @selector(moveUp:)) { // move up return YES; } else if(commandSelector == @selector(moveDown:)){ // move down return YES; } return NO; } 

For now, I could use this to then move the row selection up / down using something like:

 [self.tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:currentRow Β± 1] byExtendingSelection:NO]; 

The problem is that I created section header lines that should not be selected, and I disabled the selection of these lines using the NSTableViewDelegate method:

 - (BOOL)tableView: (NSTableView *)tableView shouldSelectRow: (NSInteger)row 

But what happens is that the selectRowIndexes:indexSetWithIndex:currentRowbyExtendingSelection: method selects the header row, although the delegate method says that the row cannot be selected.

It seems you can still select rows programmatically, regardless of what NSTableViewDelegate says. I want the selection to move the header lines.

If NSTableView is firstResponder , then inline keyboard controls skip header lines.

So my question is, is there a way to move events up / down in an NSTableView to create a built-in mechanism to move the selection?

+3
cocoa keyboard nstableview macos nsevent
source share
2 answers

The following works for me, but I'm not sure if there are any side effects.

 - (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector { if (commandSelector == @selector(moveUp:)) { // move up [_tableView keyDown:[NSApp currentEvent]]; return YES; } else if(commandSelector == @selector(moveDown:)){ // move down [_tableView keyDown:[NSApp currentEvent]]; return YES; } return NO; } 
+2
source share

Your method is -control:textView:doCommandBySelector: must be in the controller, which is the delegate of the table view or data source or has access to them. Therefore, it can simply check whether the row should be selected in the same way as your delegation method. (You can call the delegate method directly, but you don't have to.)

If this method is not present in such a controller, it should send a request to this controller.

0
source share

All Articles