我有一个简单的基于NSTableView的视图,其中一列填充了Core Data实体,而row的视图只包含一个NSTextField。我只需要第一行不可编辑,并以红色显示。我试着在applicationDidFinishLaunching:
中的某个地方NSView *myView = [myPlaylistsTableView viewAtColumn:0 row:0 makeIfNecessary:NO];
NSArray *mySubviews = [myView subviews];
NSTextField *myTextField = [mySubviews firstObject];
[myTextField setEditable:NO];
NSDictionary *myDictionary = [NSDictionary dictionaryWithObjectsAndKeys:[NSColor redColor],NSForegroundColorAttributeName, nil];
NSAttributedString *myRedAttributedString = [[NSAttributedString alloc] initWithString:@"All Songs" attributes:myDictionary];
[myTextField setAttributedStringValue:myRedAttributedString];
但是只要在表格中添加新元素或执行拖动,第一行就会再次编辑。我试图编写一个值转换器,将NSTextField可编辑绑定绑定到数组控制器selectionIndex,如果selectionIndex为0,则返回NO,在所有其他情况下返回yes。这不起作用,值绑定的各种配置有条件地设置可编辑复选框。我想NSTableView的一个子类也可以做到这一点,但我在这方面有点迷失。 任何帮助总是非常感激。感谢。
正如@Joshua Nozzi所建议的那样,我正在为表视图实现这个委托方法:
-(NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
NSView *myView = [tableView makeViewWithIdentifier:[tableColumn identifier] owner:self];
if (tableView == myPlaylistsTableView)
{
if (row == 0)
{
NSArray *mySubviews = [myView subviews];
NSTextField *myTextField = [mySubviews firstObject];
[myTextField setEditable:NO];
NSDictionary *myDictionary = [NSDictionary dictionaryWithObjectsAndKeys:[NSColor redColor],NSForegroundColorAttributeName, nil];
NSAttributedString *myBoldAllSongsString = [[NSAttributedString alloc] initWithString:@"All Songs" attributes:myDictionary];
[myTextField setAttributedStringValue:myBoldAllSongsString];
}
}
return myView;
}
但我必须遗漏一些东西,因为该方法被调用正确的NSTableView和row = 0,代码被执行但我仍然没有红色字符串,文本字段是可编辑的。
再次感谢您的帮助。
答案 0 :(得分:1)
您正在尝试定位单元格视图并永久地设置它。" NSTableView
并非如此。每次重新加载一行或整个表时,受影响行的视图都会刷新""刷新"。
自定义它们的适当位置在NSTableViewDelegate
协议方法-tableView:viewForTableColumn:row:
中(请记住将实现此方法的控制器设置为表视图的委托)。
根据OP的更新进行更新
有些观点:
使用表格列的标识符作为您的单元格视图的标识符有点奇怪,因为两者可能不同。特别是如果您在同一列中有多个可能的单元格类型(常见情况)。最好进入为每个单元格视图使用唯一标识符的做法,并且如果您有多个列,则仅使用列标识符来标识列。
您在 之外查看 if()
条件,检查哪个表格正在询问。如果你只有一张桌子,请不要费心检查;如果您可能有多个使用该控制器,请确保与每个表相关的所有内容(包括-makeViewWithIdentifier :)都在其相关条件内。返回myView
也是如此 - 如果没有表匹配,那么你的最后一次返回应为零,以便进行最佳练习。
您似乎只在row == 0
时才配置您的单元格视图,但是您没有考虑已经配置为第0行但正在重复使用行的重用视图&gt ; 0。你可能会看到"有趣的"所有行的行为> 0在需要大量滚动的大表中。
您确定单元格视图的第一个子视图是NSTextField
吗?您是否在调试器控制台中看到任何消息(例如" ...does not respond to selector...
")?或者,如果您在[myTextField setEditable:NO]
行设置断点,那么当调试器暂停时,myTextField
是否为零?这里的最佳做法是将您自己的视图子类IBOutlet
s创建到您要与之交互的任何子视图中,然后以这种方式更新它们。在编辑单元格视图时,依赖于其子视图列表是一个混淆和未来错误的处方,即使它最初正在工作。
与4相关,如果你需要的只是一个文本字段作为你的单元格,为什么不使用库存NSTableCellView类(它有自己的-textField
插座)所以你可以告诉它{{1} }
myView.textField.attributedStringValue = someAttributedString
有单独的方法来设置其字符串值的字体和颜色。为什么不利用这些而不是创建和设置属性字符串?
添加:忘了提到绑定。即使您正确获取对文本字段的引用,在此处设置其属性也不会对您有所帮助,因为绑定可能会覆盖它们。更容易放弃绑定并在NSTextField
旁边实施NSTableDataSource
协议,并在数据更改时自行处理表格视图。关于UI更新的时间安排,你会给自己带来很多麻烦和困惑。
基于以上内容的重写示例:
NSTableViewDelegate