3 回答
TA贡献1820条经验 获得超9个赞
这是鸡和鸡蛋的问题。表格需要知道行高,因为它确定了给定视图的位置。但是,您希望视图已经存在,因此可以使用它来计算行高。那么,哪个先出现?
答案是保留额外的NSTableCellView(或用作“单元格视图”的任何视图)周围,仅用于测量视图的高度。在tableView:heightOfRow:委托方法中,访问模型的“行”并设置objectValueon NSTableCellView。然后将视图的宽度设置为表格的宽度,然后(无论您要执行什么操作)找出该视图所需的高度。返回该值。
请勿noteHeightOfRowsWithIndexesChanged:在委托方法tableView:heightOfRow:或viewForTableColumn:row:!中调用 那是不好的,并且会引起大麻烦。
要动态更新高度,那么您应该做的是响应文本更改(通过目标/动作)并重新计算该视图的计算高度。现在,请勿动态更改NSTableCellView的高度(或任何用作“单元格视图”的视图)。该表必须控制该视图的框架,如果尝试设置该视图,您将与之抗争。相反,在计算高度的文本字段的目标/操作中,调用 noteHeightOfRowsWithIndexesChanged:,这将使表调整该行的大小。假设您已经在子视图(即的子视图NSTableCellView)上设置了自动调整大小的蒙版设置,那么应该可以调整大小!如果不是,请首先对子视图的调整大小蒙版进行操作,以使行高度可变的东西正确无误。
不要忘记noteHeightOfRowsWithIndexesChanged:默认设置动画。要使其不动画,请执行以下操作:
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:0];
[tableView noteHeightOfRowsWithIndexesChanged:indexSet];
[NSAnimationContext endGrouping];
PS:我对Apple Dev论坛上发布的问题的回答要多于堆栈溢出。
PSS:我写了基于视图的NSTableView
TA贡献1824条经验 获得超6个赞
根据Corbin的回答(顺便说一句,感谢您对此发表一些看法):
Swift 3,基于视图的NSTableView,带有适用于macOS 10.11(及更高版本)的自动布局
我的设置:我有一个NSTableCellView使用自动版式布局的布局。它包含(除其他元素外)多行NSTextField,最多可包含2行。因此,整个单元格视图的高度取决于此文本字段的高度。
我更新告诉表格视图两次来更新高度:
1)当表格视图调整大小时:
func tableViewColumnDidResize(_ notification: Notification) {
let allIndexes = IndexSet(integersIn: 0..<tableView.numberOfRows)
tableView.noteHeightOfRows(withIndexesChanged: allIndexes)
}
2)当数据模型对象更改时:
tableView.noteHeightOfRows(withIndexesChanged: changedIndexes)
这将导致表格视图向其委托要求新的行高。
func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
// Get data object for this row
let entity = dataChangesController.entities[row]
// Receive the appropriate cell identifier for your model object
let cellViewIdentifier = tableCellViewIdentifier(for: entity)
// We use an implicitly unwrapped optional to crash if we can't create a new cell view
var cellView: NSTableCellView!
// Check if we already have a cell view for this identifier
if let savedView = savedTableCellViews[cellViewIdentifier] {
cellView = savedView
}
// If not, create and cache one
else if let view = tableView.make(withIdentifier: cellViewIdentifier, owner: nil) as? NSTableCellView {
savedTableCellViews[cellViewIdentifier] = view
cellView = view
}
// Set data object
if let entityHandler = cellView as? DataEntityHandler {
entityHandler.update(with: entity)
}
// Layout
cellView.bounds.size.width = tableView.bounds.size.width
cellView.needsLayout = true
cellView.layoutSubtreeIfNeeded()
let height = cellView.fittingSize.height
// Make sure we return at least the table view height
return height > tableView.rowHeight ? height : tableView.rowHeight
}
首先,我们需要获取模型对象的行(entity)和适当的单元格视图标识符。然后,我们检查是否已经为此标识符创建了视图。为此,我们必须维护一个列表,其中包含每个标识符的单元格视图:
// We need to keep one cell view (per identifier) around
fileprivate var savedTableCellViews = [String : NSTableCellView]()
如果没有保存,则需要创建(并缓存)一个新的。我们使用模型对象更新单元格视图,并告诉它根据当前表视图宽度重新布局所有内容。fittingSize然后可以将该高度用作新的高度。
- 3 回答
- 0 关注
- 1088 浏览
添加回答
举报