【问题标题】:NSTableView select row by pressing "space"NSTableView 通过按“空格”选择行
【发布时间】:2013-02-24 04:00:34
【问题描述】:

我没有找到关于这个问题的任何信息,我想知道是否可以通过按键盘上的空格键使 NSTableView(或子类)选择行,并通过按向上/向下键而不用选择被重置。如果有人在 Windows 下使用它,我想让 nstableview 表现得像总指挥官的文件面板。我什至不知道从哪里开始。

【问题讨论】:

    标签: cocoa selection nstableview


    【解决方案1】:

    您必须创建 NSTableView 类的子类。这是您如何做到这一点的基本示例。它使用空格键和鼠标右键处理选择,但它不处理鼠标右键拖动选择。

    想法是在单选模式下使用 NSTableView 并实现替代选择。我们添加属性 markedRows 然后使用它来代替原来的 selectedRows 属性。

    FOTableView.h

    #import <Cocoa/Cocoa.h>
    
    @interface FOTableView : NSTableView
    
    @property (strong,nonatomic) NSMutableIndexSet *markedRows;
    
    @end
    

    FOTableView.m

    #import "FOTableView.h"
    
    @implementation FOTableView
    
    - (id)initWithFrame:(NSRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
        }
    
        return self;
    }
    
    -(NSMutableIndexSet *) markedRows
    {
        if (!_markedRows) {
            _markedRows = [NSMutableIndexSet new];
        }
        return _markedRows;
    }
    
    - (void)drawRow:(NSInteger)row clipRect:(NSRect)clipRect
    {
        if ([self.markedRows containsIndex:row]) {
            NSRect clipRect = [self rectOfRow:row];
            NSColor *color =  [NSColor colorWithCalibratedRed:0.932 green:0.046 blue:0.960 alpha:1.000];
            [color setFill];
            NSRectFill(clipRect);
        }
    
        [super drawRow:row clipRect:clipRect];
    }
    
    - (void)keyDown:(NSEvent *)theEvent
    {
        NSString *keyString;
        unichar  keyChar;
    
        keyString = [theEvent charactersIgnoringModifiers];
        keyChar = [keyString characterAtIndex:0];
        NSInteger row = [self selectedRow];
        switch(keyChar){            
            case 32:
            {
                 if (row != -1)
                 {
                     if ([self.markedRows containsIndex:row]) {
                         [self.markedRows removeIndex:row];
                     }
                     else {
                         [self.markedRows addIndex:row];
                     }
                 }
                [self selectRowIndexes:[NSIndexSet indexSetWithIndex:++row] byExtendingSelection:NO];
                [self setNeedsDisplay:YES];
                break;
            }
    
            default:
                [super keyDown:theEvent];
        }
    
        NSLog(@"key pressed: (%hu)%@", keyChar,keyString);
    }
    
    - (void)rightMouseDown:(NSEvent *)theEvent
    {
        NSInteger row = [self rowAtPoint:[self convertPoint:[theEvent locationInWindow] fromView:nil]];
        if ([self.markedRows containsIndex:row]) {
            [self.markedRows removeIndex:row];
        }
        else {
            [self.markedRows addIndex:row];
        }
    
        [self setNeedsDisplay:YES];
    }
    
    @end
    

    【讨论】:

    • 谢谢你的回答,我会试试看的:)
    • @Robert 我使用这个解决方案来标记表视图中的行,但是我发现了一个问题:如果我通过单击表头对表视图进行排序,表视图会被排序,但是“markedRows”索引集没有得到排序,所以它会存储错误的标记项索引,如何解决这个问题?
    • @treblam 嗯,您应该存储每个项目的唯一内容,甚至可能是指针,然后使用它而不是索引。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多