问题
I'm trying to create a simple data entry application for the Mac (not iPhone). It has an NSTableView (inside an NSScrollView) which contains an NSTextField into which the user keys data, line by line.
What I have so far is working okay, except that in order to actually be able to type anything into the text field, you have to press the 'Enter' key first. Then when you press the 'Enter' key at the end, the field leaves 'edit' mode, but the highlight just sits on the same row. Having to press 'Enter', 'down arrow', 'Enter' between each row of data entered is not very efficient.
What I would prefer is that when you press the 'Enter' key, the cursor moves down to the next row and the field is automatically placed into 'edit' mode.
I had thought that such a thing should be fairly straightforward, but I have been tearing my hair out all evening without any progress, and I still don't even know which way I should be heading.
I tried looking for some attribute settings in the 'inspectors' in Xcode, but couldn't see anything.
Searching online, suggestions seemed to keep coming back to somehow using First Responder. Playing around with this, I've only managed to get the blue highlight ring to move down around my TableView on demand, but this still doesn't seem to put the text field into 'edit' mode nor move to another line.
Finally I found some information about subclassing and implementing your own textfields, but this seems like a very long and convoluted way to achieve this.
Can someone point me in the right direction as to how to do this?
Am I maybe using the wrong kind of control? Perhaps something else is more appropriate. Note that each line is distinct, so I don't want things like word wrap etc.
回答1:
You were on the right track with the First Responder, but it's important to not that text editing is handled by the window's Field Editor (an instance of NSTextView), which becomes the first responder when text editing begins. The field editor informs its client (in this case your Table View) during editing.
The easiest way to handle this would be to subclass NSTableView and override its textDidEndEditing: method. Something like this should get you started:
- (void) textDidEndEditing:(NSNotification *)notification {
[super textDidEndEditing:notification];
int textMovement = [[notification.userInfo valueForKey:@"NSTextMovement"] intValue];
if (NSReturnTextMovement == textMovement) {
NSText *fieldEditor = notification.object;
// The row and column for the cell that just ended editing
NSInteger row = [self rowAtPoint:fieldEditor.frame.origin];
NSInteger col = [self columnAtPoint:fieldEditor.frame.origin];
if (++col >= self.numberOfColumns) {
col = 0;
if (++row >= self.numberOfRows) return;
}
[self selectRowIndexes:[NSIndexSet indexSetWithIndex:row]
byExtendingSelection:NO];
[self editColumn:col row:row withEvent:nil select:YES];
}
}
This will progress left-to-right, top-to-bottom through the table's columns and rows. Though you said you were using a NSTextField, I presume you meant you were using a NSTextFieldCell in a cell-based table. That's another important distinction. If you're not familiar with the concept of the field editor, I suggest you read up.
来源:https://stackoverflow.com/questions/7850607/change-enter-key-behaviour-in-nstableview