【问题标题】:NSMatrix with multiple toggle buttons?具有多个切换按钮的 NSMatrix?
【发布时间】:2012-05-29 07:31:32
【问题描述】:

我正在尝试创建一个NSMatrixNSButtonCells,其中可以选择零到四个按钮(打开)。我尝试了以下(测试)代码,但不确定如何提供所需的功能。也许NSMatrix 不可能,我需要查看替代控件,或者创建自己的控件?

@interface MatrixView : NSView
{
    NSScrollView *_scrollView;
    NSMatrix *_matrixView;
}
@end

@implementation MatrixView

- (id)initWithFrame:(NSRect)frameRect
{
    NSLog(@"initWithFrame. frameRect=%@", NSStringFromRect(frameRect));
    self = [super initWithFrame:frameRect];
    if (self != nil)
    {
        _scrollView = [[NSScrollView alloc] initWithFrame:NSMakeRect(0, 0, frameRect.size.width, frameRect.size.height)];
        [_scrollView setBorderType:NSNoBorder];
        [_scrollView setHasVerticalScroller:YES];
        [_scrollView setHasHorizontalScroller:NO];
        [_scrollView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];

        NSSize contentSize = [_scrollView contentSize];
        contentSize.height = 300;

        // Make it 3 x however-many-buttons-will-fit-the-height
        CGFloat gap = 8.0;
        CGFloat width = (contentSize.width / 3.0) - (gap * 2.0);
        NSUInteger rows = (contentSize.height / (width + gap));

        NSLog(@"width=%f, rows=%lu", width, rows);

        NSButtonCell *prototype = [[NSButtonCell alloc] init];
        [prototype setTitle:@"Hello"];
        [prototype setButtonType:NSToggleButton];
        [prototype setShowsStateBy:NSChangeGrayCellMask];
        _matrixView = [[NSMatrix alloc] initWithFrame:NSMakeRect(0, 0, contentSize.width, contentSize.height)
                                                 mode:NSListModeMatrix
                                            prototype:prototype
                                         numberOfRows:rows
                                      numberOfColumns:3];
        [_matrixView setCellSize:NSMakeSize(width, width)];
        [_matrixView setIntercellSpacing:NSMakeSize(gap, gap)];
        [_matrixView setAllowsEmptySelection:YES];
        [_matrixView sizeToCells];
        [_scrollView setDocumentView:_matrixView];
        [self addSubview:_scrollView];
        [self setAutoresizesSubviews:YES];
        [prototype release];
    }

    return self;
}

...

【问题讨论】:

  • 你当然可以拥有一个带有多个切换按钮的矩阵——我在 IB 中制作了一个,带有 NSButtonCells(推上推下类型)和高亮模式下的矩阵。这显示了在您再次按下它们之前一直突出显示的按钮。仅将其限制为 4 个,有点棘手 - 还没有完全弄清楚那个。
  • @rdelmar 我刚刚将上面的代码更改为使用按下按钮并将矩阵置于高亮模式,但它不能按预期工作(按下-push-off 模式被矩阵覆盖,没有任何东西被推入)。还有什么需要设置的吗?

标签: objective-c cocoa multi-select nsmatrix nsbuttoncell


【解决方案1】:

我让它与以下 NSMatrix 子类一起使用。我添加了一个属性 onCount,以跟踪处于开启状态的按钮数量:

@implementation RDMatrix
@synthesize onCount;

-(id) initWithParentView:(NSView *) cv {
    NSButtonCell *theCell = [[NSButtonCell alloc ]init];
    theCell.bezelStyle = NSSmallSquareBezelStyle;
    theCell.buttonType = NSPushOnPushOffButton;
    theCell.title = @"";
    if (self = [super initWithFrame:NSMakeRect(200,150,1,1) mode:2 prototype:theCell numberOfRows:4 numberOfColumns:4]){ 
        [self setSelectionByRect:FALSE];
        [self setCellSize:NSMakeSize(40,40)];
        [self sizeToCells];
        self.target = self;
        self.action = @selector(buttonClick:);
        self.drawsBackground = FALSE;
        self.autoresizingMask = 8;
        self.allowsEmptySelection = TRUE;
        self.mode = NSHighlightModeMatrix;
        self.onCount = 0;
        [cv addSubview:self];
        return self;
    }
    return nil;
}


-(IBAction)buttonClick:(NSMatrix *)sender {
    NSUInteger onOrOff =[sender.selectedCells.lastObject state];
    if (onOrOff) {
        self.onCount += 1;
    }else{
        self.onCount -= 1;
    }
    NSLog(@"%ld",self.onCount);
    if (self.onCount == 5) {
        [sender.selectedCells.lastObject setState:0];
        self.onCount -= 1;
    }    
}

当您尝试选择第 5 个按钮时,它会闪烁,然后熄灭。这可能是一个问题,具体取决于您如何使用这些按钮的状态。我只是用这种方法记录了它们:

-(IBAction)checkMatrix:(id)sender {
    NSIndexSet *indxs = [self.mat.cells indexesOfObjectsPassingTest:^BOOL(NSButtonCell *cell, NSUInteger idx, BOOL *stop) {
        return cell.state == NSOnState;
    }];
    NSLog(@"%@",indxs);
}

编辑后:我不喜欢我的第一个方法在您尝试单击第 5 个按钮时再次关闭按钮之前短暂闪烁按钮的方式。我发现我认为更好的解决方案涉及在矩阵子类中覆盖 mouseDown(如果你想尝试这个,你应该删除 setAction 和 setTarget 语句并删除 buttonClick 方法):

-(void)mouseDown:(NSEvent *) event {
    NSPoint matPoint = [self convertPoint:event.locationInWindow fromView:nil];
    NSInteger row;
    NSInteger column;
    [self getRow:&row column:&column forPoint:matPoint];
    NSButtonCell *cell = [self cellAtRow:row column:column];
    if (self.onCount < 4 && cell.state == NSOffState) {
        cell.state = NSOnState;
        self.onCount += 1;
    }else if (cell.state == NSOnState) {
        cell.state = NSOffState;
        self.onCount -= 1;
    }
}

【讨论】:

  • @trojanfoe :我对用于限制可处于开启状态的按钮数量的方法不满意,因此我想出了我认为更好的解决方案。请参阅我编辑的答案。
  • 别担心我是否使用了不同的计数代码,无论如何都会禁用未选择的按钮时4。您回答的关键是使用目标方法并找出刚刚按下的按钮。
猜你喜欢
  • 2016-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-15
  • 2012-07-09
相关资源
最近更新 更多