NSTableView中的Check类型的NSButtonCell不允许更改值

时间:2011-11-10 10:12:21

标签: cocoa operating-system nstableview nsbuttoncell

我有3个表视图的窗口(10.7.2,Xcode 4.2)。 它们都是在IB中创建的,NSButtonCells与出口连接。

我创建了控制器类,并用一些示例数据填充了所有三个视图:

- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView {
    return 10;
}

- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn    *)aTableColumn row:(NSInteger)rowIndex {

NSButtonCell *buttonCell;

if(aTableView == dimensionTable) {    
    [dimensionButtonCell setTitle:@"Dimension"];
    buttonCell = dimensionButtonCell;
}
else if(aTableView == shopTable) {
    [shopButtonCell setTitle:@"Shop"];
    buttonCell = shopButtonCell;
}
else if(aTableView == countryTable) {
    [countryButtonCell setTitle:@"Country"];
    buttonCell = countryButtonCell;
}


return buttonCell;

}

我有两个问题:

  1. 我无法通过GUI更改复选框状态。不过,我可以以编程方式更改它。当您按住鼠标按钮时,它会闪烁一点,但不允许更改......

  2. 我尝试用视图填充数据,没有出口到单元格。它没用。单元格视图中的NSButtonCell cels是否与基于视图的表视图或基于“普通”cel的表视图有所不同?

1 个答案:

答案 0 :(得分:4)

经过长时间的努力,我设法找到解决问题的方法。问题的一部分是数据模型方面的简单错误,但这并不重要,使用NSTableView委托和数据源要做的事情要困难得多。

这主要是3个难以阻止良好理解和解决这个问题的难题:

  • apple的文档对表视图的数据源和其委托的- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex中的- (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row的差异和典型用法缺乏任何合理的解释。虽然看起来你可能需要后一种方法,因为NSButtonCells是自定义NSCells,但事实证明它没有必要,但我还是把它留在了最后。

  • NSTableView方法中的内部转换

  • 几乎在网上的任何地方都没有记录问题

以下是您应该采取的步骤:

- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex {

    buttonCell = [aTableColumn dataCell];

    NSString *columnKey = [aTableColumn identifier];

    return buttonCell;

}

无论您是否使用此方法,都可以看到此方法。

- (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {

    buttonCell = [tableColumn dataCell];

    NSString *columnKey = [tableColumn identifier];

    if(tableView == dimensionTable) {    

//        returnObject = @"Dimension";
        //        [dimensionButtonCell setTitle:@"Dimension"];
        //        buttonCell = dimensionButtonCell;
    }

    else if(tableView == shopTable) {

        [buttonCell setState:[[mySelectedShops objectAtIndex:row] integerValue]];
        [buttonCell setTitle:[myShops objectAtIndex:row]];

    }

    else if(tableView == countryTable) {

        [buttonCell setState:[[mySelectedCountries objectAtIndex:row] integerValue]];
        [buttonCell setTitle:[myCountries objectAtIndex:row]];

    }

    return buttonCell;

}

你可以看到我使用了第二种方法,但objectValueForTableColumn可以单独使用。 您还可以看到,我有NSMutableArray mySelectedShops和mySelectedCountries来保存表视图中每行包含在NSNumber中的NSInteger(1或0)。

如果设置NSCell的state或integerValue没有区别。两者都将使用NSInteger类型的值1或0来检查和取消选中NSButtonCell。

- (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex {

    NSString *columnKey = [aTableColumn identifier];

    if(aTableView == dimensionTable) {    
//        [dimensionButtonCell setTitle:@"Dimension"];
//        buttonCell = dimensionButtonCell;
    }
    else if(aTableView == shopTable) {

        [mySelectedShops replaceObjectAtIndex:rowIndex withObject:[NSNumber numberWithInteger:[(NSCell*)anObject integerValue]]];

    }
    else if(aTableView == countryTable) {

        [mySelectedCountries replaceObjectAtIndex:rowIndex withObject:[NSNumber numberWithInteger:[(NSCell*)anObject integerValue]]];

    }

}

虽然我将NSInteger值传递给NSCell对象,但这里的anObject是__NSCFBoolean类型,这意味着某些东西不能按预期工作。为了能够将对象值替换为数组,我将其转换为NSCell只是为了获得integerValues。它实际上也没有演员阵容,所以这对我来说是另一个谜,但我更喜欢它。

很明显Apple正在转向基于UITableView的基于视图的细胞。不过,我希望这会对某人有所帮助。