我有一个NSTableView,可以根据行的数据值交换不同的单元格视图。当模型更改时,我重新加载表格,表格的委托将为新数据提供正确的表格单元格视图。
该表格使用自动布局来处理其单元格视图。所有单元格视图最初都会正常加载。在模型更改后更新表格时,根据调用
我创建了一个示例项目来演示问题。 这里是项目设置的图像,包括对表格单元格视图设置的约束。有两个行模板,一个带有蓝色视图(偶数行),一个带有绿色视图(奇数行),应跨越表格宽度(减去一些填充)。控制器提供单元格视图:
界面中的一个按钮只是交换了第一行的数据并重新加载数据。初始视图看起来像这样(交替显示绿色和蓝色方块)。如果使用
文档提到,使用
更新:这是ColorView的代码:
该表格使用自动布局来处理其单元格视图。所有单元格视图最初都会正常加载。在模型更改后更新表格时,根据调用
reloadData()
或reloadData(forRowIndexes:columnIndexes)
而产生不同的结果。使用reloadData()
时,单元格视图被加载且自动布局正常工作。如果使用reloadData(forRowIndexes:columnIndexes)
,则自动布局会产生完全不同和意外的结果。我创建了一个示例项目来演示问题。 这里是项目设置的图像,包括对表格单元格视图设置的约束。有两个行模板,一个带有蓝色视图(偶数行),一个带有绿色视图(奇数行),应跨越表格宽度(减去一些填充)。控制器提供单元格视图:
class TableController: NSObject {
@IBOutlet weak var tableView: NSTableView!
var colorData = [1, 0, 1, 0]
@IBAction func swapLine(_ sender: Any) {
colorData[1] = (colorData[1] + 1) % 2
// tableView.reloadData()
tableView.reloadData(forRowIndexes: [1], columnIndexes: [0])
}
}
extension TableController: NSTableViewDataSource {
func numberOfRows(in tableView: NSTableView) -> Int {
return colorData.count
}
}
extension TableController: NSTableViewDelegate {
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
let cellId = (colorData[row]) % 2 == 0 ? "EvenCell" : "OddCell"
return tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(cellId), owner: self)
}
}
界面中的一个按钮只是交换了第一行的数据并重新加载数据。初始视图看起来像这样(交替显示绿色和蓝色方块)。如果使用
reloadData()
,它看起来像这样(第1行从蓝色变为绿色)。但是,如果使用reloadData(withRowIndexes:columnIndexes:)
,单元格视图会缩小到40个点,而不是其他情况下的480个点。这里是视图调试器中显示的具有错误大小的单元格视图以及显示模棱两可的宽度约束的截图(使用reloadData()
时不会发生这种情况)。文档提到,使用
reloadData(forRowIndexes:columnIndexes:)
重用了行视图,但使用reloadData()
没有,我已经验证过了。我想这个行视图的重用是导致自动布局问题的原因,但我找不到关联。在SO、AppKit发布说明、WWDC视频、Google搜索或敲打桌子时什么都没有找到。如果能得到帮助,将不胜感激。更新:这是ColorView的代码:
class ColorView: NSView {
@IBInspectable var intrinsicHeight: CGFloat = 20
@IBInspectable var color: NSColor = NSColor.blue
override var intrinsicContentSize: NSSize {
return NSSize(width: NSView.noIntrinsicMetric, height: intrinsicHeight)
}
override func draw(_ dirtyRect: NSRect) {
color.setFill()
dirtyRect.fill()
}
}
NSView
替换了NSTableCellView
? - WillekeNSTableCellView
的子类)单元格视图或具有与默认单元格视图相同的autoresizingMask
的单元格视图。 - Willekefunc tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat
。您可以根据tableView的边界计算宽度,然后使用该宽度计算文本的行高。在textView上使用自动布局,以便它随着行高缩放。这是我在我们的应用程序中采用的方法,效果非常好。高度计算是最困难的部分,但无论采用哪种方法都必须处理它。 - Nima Yousefi