gpt4 book ai didi

objective-c - Cocoa 如何对基于 NSTableView 的 View 中的特定行强制执行特定的编辑行为?

转载 作者:行者123 更新时间:2023-12-03 17:10:54 25 4
gpt4 key购买 nike

我有一个基于 NSTableView 的简单 View ,其中一列填充有核心数据实体,而行 View 仅包含一个 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 可编辑绑定(bind)绑定(bind)到数组 Controller 选择索引,如果选择索引为 0,则返回“否”,在所有其他情况下返回"is"。对于值绑定(bind)的条件设置可编辑复选框的各种配置,这不起作用。我想 NSTableView 的子类也应该可以解决这个问题,但我在这方面有点迷失。一如既往,我们非常感谢任何帮助。谢谢。

根据@Joshua Nozzi的建议,我正在为 TableView 实现此委托(delegate)方法:

-(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 调用的,代码被执行,但我仍然没有红色字符串,并且文本字段是可编辑的。

再次感谢您的帮助。

最佳答案

您正在尝试定位单元格 View 并将其设置为“永远”。 NSTableView 并不完全是这样工作的。每次重新加载一行或整个表时,受影响行的 View 都会“刷新”。

自定义它们的适当位置是在 NSTableViewDelegate 协议(protocol)方法 -tableView:viewForTableColumn:row: 中(记住将实现此方法的 Controller 设置为 TableView 的委托(delegate))。

根据OP的更新进行更新

几点:

  1. 使用表列的标识符作为单元格 View 的标识符有点奇怪,因为两者可能不同。特别是当同一列中有多种可能的单元格类型时(常见情况)。最好养成为每个单元格 View 使用唯一标识符的做法,并且如果您有多个单元格 View ,则仅使用列标识符来标识该列。

  2. 您将 View 设置在 if() 条件之外,以检查哪个表正在询问。如果你只有一张 table ,就不用费心去检查;如果您可能有多个正在使用该 Controller ,请确保与每个表相关的所有内容(包括 -makeViewWithIdentifier:)都位于其相关条件内。返回 myView 相同 - 应该移入您的条件,如果没有表匹配,则最佳实践的最后返回应该为零。

  3. 您似乎仅在 row == 0 时才配置单元格 View ,但您未能考虑已被配置为第 0 行单元格但正在被重用于行>0。您可能会在需要大量滚动的大表中看到所有 >0 行的“有趣”行为。

  4. 您确定单元格 View 的第一个 subview 是您的 NSTextField 吗?您是否在调试器控制台中看到任何消息(例如“...不响应选择器...”)?或者,如果您在 [myTextField setEditable:NO] 行上设置断点,那么当调试器暂停时 myTextField 是否为零?这里的最佳实践是使用 IBOutlet 为您想要与之交互的任何 subview 创建您自己的 View 子类,然后以这种方式更新它们。当您编辑单元格 View 时,依赖其 subview 列表会导致困惑和 future 的错误,即使它一开始是有效的。

  5. 与 4 相关,如果您需要的只是一个文本字段作为单元格,为什么不使用现有的 NSTableCellView 类(它有自己的 -textField 导出),这样您就可以告诉它myView.textField.attributedStringValue = someAttributedString

  6. NSTextField 有单独的方法来设置其字符串值的字体和颜色。为什么不利用这些而不是创建和设置属性字符串?

  7. 添加:忘记了您提到的绑定(bind)。即使您正确获取了对文本字段的引用,在此处设置其属性也不会帮助您,因为绑定(bind)可能会覆盖它们。更容易放弃绑定(bind)并与 NSTableViewDelegate 一起实现 NSTableDataSource 协议(protocol),并在数据更改时自行刷新 TableView 。您将为自己省去很多关于 UI 更新时间的头痛和困惑。

基于上述重写的示例:

-(NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{

// Is it the right table view?
if (tableView == myPlaylistsTableView)
{

// Determine properties based on row
BOOL firstRow = (row == 0);
NSFont * font = (firstRow) ? [NSFont systemFontOfSize:[NSFont systemFontSize]] : [NSFont boldSystemFontOfSize:[NSFont systemFontSize]];
NSString * text = (firstRow) ? @"All Songs" : [self.songsList[ row ] songTitle]; // or whatever other row titles will be
NSColor * color = (firstRow) ? [NSColor redColor] : [NSColor labelColor];

// Make an configure a cell view
NSTableCellView * myView = [tableView makeViewWithIdentifier:@"TextCell" owner:nil];
NSTextField * textField = myView.textField;
textField.editable = !firstRow;
textField.stringValue = text;
textField.font = font;
textField.textColor = color;

return myView;

}

return nil;
}

关于objective-c - Cocoa 如何对基于 NSTableView 的 View 中的特定行强制执行特定的编辑行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29928026/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com