代码之家  ›  专栏  ›  技术社区  ›  dreamlax

带NSTableView的箭头键

  •  15
  • dreamlax  · 技术社区  · 17 年前

    是否可以使用箭头键和enter/tab在NSTableView的可编辑单元格中导航?例如,我想让它感觉更像一个电子表格。

    这个应用程序的用户需要编辑相当多的单元格(但不是全部),我认为如果他们不必双击每个单元格,这样做会更容易。

    4 回复  |  直到 17 年前
        1
  •  10
  •   Jakob Egger    16 年前

    control:textView:doCommandBySelector:

    - (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command
    {
        NSUInteger row, column;
    
        row = [tableView editedRow];
        column = [tableView editedColumn];
    
        // Trap down arrow key
        if (  [textView methodForSelector:command] == [textView methodForSelector:@selector(moveDown:)] )
        {
            NSUInteger newRow = row+1;
            if (newRow>=numRows) return TRUE; //check if we're already at the end of the list
            if (column>= numColumns) return TRUE; //the column count could change
    
            [tableContentView selectRowIndexes:[NSIndexSet indexSetWithIndex:newRow] byExtendingSelection:NO];
            [tableContentView editColumn:column row:newRow withEvent:nil select:YES];
            return TRUE;
        }
    
        // Trap up arrow key
        else if (  [textView methodForSelector:command] == [textView methodForSelector:@selector(moveUp:)] )
        {
            if (row==0) return TRUE; //already at the beginning of the list
            NSUInteger newRow = row-1;
    
            if (newRow>=numRows) return TRUE;
            if (column>= numColumns) return TRUE;
    
            [tableContentView selectRowIndexes:[NSIndexSet indexSetWithIndex:newRow] byExtendingSelection:NO];
            [tableContentView editColumn:column row:newRow withEvent:nil select:YES];
            return TRUE;
        }
    
        2
  •  5
  •   dreamlax    17 年前

    1. NSTextView MyFieldEditorClass myFieldEditor 将引用此类的一个实例。

    2. - (void) setLastKnownColumn:(unsigned)aCol andRow:(unsigned) aRow

    3. - (void) keyDown:(NSEvent *) event NSResponder keyDown: < > &lt; &gt;

      - (void) keyDown:(NSEvent *) event
      {
          unsigned newRow = row, newCol = column;
          switch ([event keyCode])
          {
              case 126: // Up
                  if (row)
                  newRow = row - 1;
                  break;
      
              case 125: // Down
                  if (row < [theTable numberOfRows] - 1)
                      newRow = row + 1;
                  break;
      
              case 123: // Left
                  if (column > 1)
                      newCol = column - 1;
                  break;
      
              case 124: // Right
                  if (column < [theTable numberOfColumns] - 1)
                      newCol = column + 1;
                  break;
      
              default:
                  [super keyDown:event];
                  return;
          }
      
          [theTable selectRow:newRow byExtendingSelection:NO];
          [theTable editColumn:newCol row:newRow withEvent:nil select:YES];
          row = newRow;
          column = newCol;
      }
      
    4. 为笔尖中的NSTableView指定一个代理,并在代理中添加以下方法:

      - (BOOL) tableView:(NSTableView *)aTableView shouldEditColumn:(NSTableColumn *) aCol row:aRow
      {
          if ([aTableView isEqual:TheTableViewYouWantToChangeBehaviour])
              [myFieldEditor setLastKnownColumn:[[aTableView tableColumns] indexOfObject:aCol] andRow:aRow];
          return YES;
      }
      
    5. 最后,给Table View的主窗口一个委托并添加方法:

      - (id) windowWillReturnFieldEditor:(NSWindow *) aWindow toObject:(id) anObject
      {
          if ([anObject isEqual:TheTableViewYouWantToChangeBehaviour])
          {
              if (!myFieldEditor)
              {
                  myFieldEditor = [[MyFieldEditorClass alloc] init];
                  [myFieldEditor setTableView:anObject];
              }
              return myFieldEditor;
          }
          else
          {
              return nil;
          }
      }
      

        3
  •  1
  •   Matt Ball    17 年前

    NSTableView MBTableGrid

        4
  •  1
  •   Robert Harvey    15 年前

    我想在这里回复答案,但回复按钮似乎不见了,所以当我真的只想问一个关于回复的问题时,我不得不证明一个答案。

    我使我用作委托的类从NSResponder而不是NSObject继承,并在awakeFromNib中将nextResponder设置为该类。然后,我能够使用keydown事件捕获按键。当然,我连接了IBOutlet并在Interface Builder中设置了代理。

    头文件

    //  AppController.h
    
    #import <Cocoa/Cocoa.h>
    
    @interface AppController : NSResponder {
    
        IBOutlet NSTableView *toDoListView;
        NSMutableArray *toDoArray;
    }
    
    -(int)numberOfRowsInTableView:(NSTableView *)aTableView;
    
    -(id)tableView:(NSTableView *)tableView
    objectValueForTableColumn:(NSTableColumn *)aTableColumn
               row:(int)rowIndex;
    
    @end
    

    这是m文件。

    //  AppController.m
    #import "AppController.h"
    
    @implementation AppController
    
    -(id)init
    {
        [super init];
        toDoArray = [[NSMutableArray alloc] init];
        return self;
    }
    
    -(void)dealloc
    {
        [toDoArray release];
        toDoArray = nil;
        [super dealloc];
    }
    
    -(void)awakeFromNib
    {
        [toDoListView setNextResponder:self];
    }
    
    -(int)numberOfRowsInTableView:(NSTableView *)aTableView
    {
        return [toDoArray count];
    }
    
    -(id)tableView:(NSTableView *)tableView
        objectValueForTableColumn:(NSTableColumn *)aTableColumn
                              row:(int)rowIndex
    {
        NSString *value = [toDoArray objectAtIndex:rowIndex];
        return value;
    }
    
    - (void)keyDown:(NSEvent *)theEvent
    {
        //NSLog(@"key pressed: %@", theEvent);
        if (theEvent.keyCode == 51 || theEvent.keyCode == 117)
        {
            [toDoArray removeObjectAtIndex:[toDoListView selectedRow]];
            [toDoListView reloadData];
        }
    }
    @end