我有一个带有 3 个表格 View 的窗口(10.7.2,Xcode 4.2)。 它们都是在 IB 中创建的,并且 NSButtonCells 与导出相连。
我创建了 Controller 类,并用一些示例数据填充了所有三个 View :
- (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;
}
我有 2 个问题:
我无法通过 GUI 更改复选框状态。不过,我可以通过编程方式更改它。当您按住鼠标按钮时,它会闪烁一点,但不允许更改...
我尝试像使用 View 一样填充数据,而不使用单元格的导出。它不起作用。单元格 View 中的 NSButtonCell 单元格与基于 View 的表格 View 或“正常”基于单元格的表格 View 有什么不同吗?
最佳答案
经过长期的努力,我终于找到了问题的解决方案。问题的一部分是数据模型方面的简单错误,但这并不重要,更困难的是使用 NSTableView 委托(delegate)和数据源来完成。
主要有 3 个困难阻碍了对这个问题的良好理解和管理:
Apple 的文档缺乏关于
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex 的差异和典型用法的任何合理解释
在 TableView 的数据源和其委托(delegate)的- (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 来为 TableView 中的每一行保存包裹在 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 只是为了获取整数值。它实际上不需要类型转换也能工作,所以这对我来说是另一个谜,但我更喜欢这样。
很明显,Apple 正在转向基于 View 的单元格,例如 UITableView。尽管如此,我还是希望这会对某人有所帮助。
关于cocoa - NSTableView 中 Check 类型的 NSButtonCell 不允许更改值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8077875/