Navigating a TableView: A Solution
Navigating a TableView: A Solution
- Subject: Navigating a TableView: A Solution
- From: Peter Bates <email@hidden>
- Date: Sat, 11 Mar 2006 11:48:00 -0700
In some of my table views with editable cells, I want the user to be
able to navigate up and down rows using arrow keys. I want a new row
to be added if the user tabs in the last cell of the last row, or if
he/she presses the down arrow in the last row. I want shift tab to
navigate to the previous cell. When the user selects a row and
presses the delete key, I want the row deleted, but not if it's the
only remaining row. Finally, I want to be able to have more than one
tableview.
This is how I made it work:
I subclassed NSWindow, added outlets for each tableview, and
implemented:
- sendEvent:(NSEvent *) theEvent
{
if ([theEvent type] == NSKeyDown)
{
switch ([[theEvent charactersIgnoringModifiers] characterAtIndex:0])
{
case NSUpArrowFunctionKey:
case NSDownArrowFunctionKey:
case NSTabCharacter:
if([self comingFromTableClass:[MyFirstTableView class]])
[firstTable keyDown:theEvent];
else if([self comingFromTableClass:[MySecondTableView class]])
[secondTable keyDown:theEvent];
else if([self comingFromTableClass:[MyThirdTableView class]])
[thirdTable keyDown:theEvent];
break;
}
}
[super sendEvent:theEvent];
}
-(BOOL) comingFromTableClass:(Class)aClass
{
NSText * fr;
fr=[self firstResponder];
if([fr isKindOfClass:[NSText class]])
{
id tableView=[fr delegate];
if([tableView isMemberOfClass:aClass])
return YES;
else
return NO;
}
else
return NO;
}
I subclassed NSTableView for each table that I wanted, added an
outlet for the respective array controller, and implemented:
// Load an initial empty row
-(void) awakeFromNib
{
MyDataObj *newRow = [[MyDataObj alloc]init];
[arrayController insertObject:newRow atArrangedObjectIndex:0];
[self selectRow:0 byExtendingSelection:NO];
[self editColumn:0 row:[self selectedRow] withEvent:nil select:YES];
// Leaking here ?
}
-(void)keyDown:(NSEvent *)anEvent
{
unichar key = [[anEvent charactersIgnoringModifiers]
characterAtIndex:0];
int r=[self selectedRow];
int c=[self editedColumn];
int lr=[self numberOfRows];
int lc=[self numberOfColumns]-1;
// First, commit the last edit.
[self textShouldEndEditing:[self delegate]];
if ((r == lr-1) && (c == lc) && (key==NSTabCharacter))
{
GNInfusionObj *newRow = [[GNInfusionObj alloc]init];
[arrayController insertObject:newRow atArrangedObjectIndex:
[[arrayController arrangedObjects] count]];
[self selectRow:lr-1 byExtendingSelection:NO];
[self editColumn:lc row:[self selectedRow] withEvent:nil select:YES];
}
else if((r==lr-1) && (key==NSDownArrowFunctionKey))
{
GNInfusionObj *newRow = [[GNInfusionObj alloc]init];
[arrayController insertObject:newRow atArrangedObjectIndex:
[[arrayController arrangedObjects] count]];
[self selectRow:lr byExtendingSelection:NO];
[self editColumn:c row:lr withEvent:anEvent select:YES];
}
else if((r<(lr-1)) && (key==NSDownArrowFunctionKey))
{
[self selectRow:r+1 byExtendingSelection:NO];
[self editColumn:c row:r+1 withEvent:anEvent select:YES];
}
else if((r>0) && (key==NSUpArrowFunctionKey))
{
[self selectRow:r-1 byExtendingSelection:NO];
[self editColumn:c row:r-1 withEvent:anEvent select:YES];
}
else if((key==NSDeleteCharacter) && ([self numberOfRows]>1))
[arrayController removeObjectAtArrangedObjectIndex:[self
selectedRow]];
}
I'm a noobie, so this may not be the best way to do it, but it does
work. Thought this might help someone else trying to get this sort
of behavior.
Thanks to all who helped. The code here is not all my original
thought. I snagged bits from several sources.
Suggestions for improvement are most welcome.
-- Pete
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden