问题描述
我有一个包含基于视图的 NSTableView
的应用程序.在这个表视图中,我有一些行,这些行的单元格的内容由启用自动换行的多行 NSTextField
组成.根据 NSTextField
的文本内容,显示单元格所需的行大小会有所不同.
I have an application with a view-based NSTableView
in it. Inside this table view, I have rows that have cells that have content consisting of a multi-row NSTextField
with word-wrap enabled. Depending on the textual content of the NSTextField
, the size of the rows needed to display the cell will vary.
我知道我可以实现 NSTableViewDelegate
方法 -tableView:heightOfRow:
来返回高度,但高度将根据在NSTextField
.NSTextField
的自动换行同样基于 NSTextField
的宽度……这由 NSTableView
的宽度决定.
I know that I can implement the NSTableViewDelegate
method -tableView:heightOfRow:
to return the height, but the height will be determined based on the word wrapping used on the NSTextField
. The word wrapping of the NSTextField
is similarly based on how wide the NSTextField
is… which is determined by the width of the NSTableView
.
太好了……我想我的问题是……什么是好的设计模式?似乎我尝试的一切都变得一团糟.由于 TableView 需要了解单元格的高度来布置它们……而 NSTextField
需要了解其布局以确定自动换行……而单元格需要了解自动换行来确定它的高度……这是一个圆形的烂摊子……它让我发疯.
Soooo… I guess my question is… what is a good design pattern for this? It seems like everything I try winds up being a convoluted mess. Since the TableView requires knowledge of the height of the cells to lay them out... and the NSTextField
needs knowledge of it's layout to determine the word wrap… and the cell needs knowledge of the word wrap to determine it's height… it's a circular mess… and it's driving me insane.
建议?
如果重要的话,最终结果也会有可编辑的 NSTextFields
,它会调整大小以适应其中的文本.我已经在视图级别上进行了这项工作,但是 tableview 还没有调整单元格的高度.我想一旦我解决了高度问题,我将使用 -noteHeightOfRowsWithIndexesChanged
方法通知表格视图高度发生了变化……但它仍然会向委托询问高度……因此,我的问题.
If it matters, the end result will also have editable NSTextFields
that will resize to adjust to the text within them. I already have this working on the view level, but the tableview does not yet adjust the heights of the cells. I figure once I get the height issue worked out, I'll use the -noteHeightOfRowsWithIndexesChanged
method to inform the table view the height changed… but it's still then going to ask the delegate for the height… hence, my quandry.
提前致谢!
推荐答案
这是鸡与蛋的问题.表格需要知道行高,因为它决定了给定视图的位置.但是您希望视图已经存在,以便您可以使用它来计算行高.那么,哪个先呢?
This is a chicken and the egg problem. The table needs to know the row height because that determines where a given view will lie. But you want a view to already be around so you can use it to figure out the row height. So, which comes first?
答案是保留一个额外的 NSTableCellView
(或您用作单元格视图"的任何视图),仅用于测量视图的高度.在 tableView:heightOfRow:
委托方法中,访问row"的模型并在 NSTableCellView
上设置 objectValue
.然后将视图的宽度设置为您的表格的宽度,并且(无论您想这样做)找出该视图所需的高度.返回那个值.
The answer is to keep an extra NSTableCellView
(or whatever view you are using as your "cell view") around just for measuring the height of the view. In the tableView:heightOfRow:
delegate method, access your model for 'row' and set the objectValue
on NSTableCellView
. Then set the view's width to be your table's width, and (however you want to do it) figure out the required height for that view. Return that value.
不要在委托方法 tableView:heightOfRow:
或 viewForTableColumn:row:
中调用 noteHeightOfRowsWithIndexesChanged:
!那不好,会引起大麻烦.
Don't call noteHeightOfRowsWithIndexesChanged:
from in the delegate method tableView:heightOfRow:
or viewForTableColumn:row:
! That is bad, and will cause mega-trouble.
要动态更新高度,那么您应该做的是响应文本更改(通过目标/动作)并重新计算该视图的计算高度.现在,不要动态更改 NSTableCellView
的高度(或您用作单元格视图"的任何视图).表格必须控制该视图的框架,如果您尝试设置它,您将与表格视图作斗争.相反,在您计算高度的文本字段的目标/操作中,调用 noteHeightOfRowsWithIndexesChanged:
,这将使表格调整单个行的大小.假设您在子视图(即:NSTableCellView
的子视图)上设置了自动调整大小掩码,那么事情应该可以很好地调整大小!如果没有,请首先处理子视图的调整大小掩码,以使用可变行高来解决问题.
To dynamically update the height, then what you should do is respond to the text changing (via the target/action) and recalculate your computed height of that view. Now, don't dynamically change the NSTableCellView
's height (or whatever view you are using as your "cell view"). The table must control that view's frame, and you will be fighting the tableview if you try to set it. Instead, in your target/action for the text field where you computed the height, call noteHeightOfRowsWithIndexesChanged:
, which will let the table resize that individual row. Assuming you have your autoresizing mask setup right on subviews (i.e.: subviews of the NSTableCellView
), things should resize fine! If not, first work on the resizing mask of the subviews to get things right with variable row heights.
不要忘记 noteHeightOfRowsWithIndexesChanged:
默认情况下会设置动画.使其不动画:
Don't forget that noteHeightOfRowsWithIndexesChanged:
animates by default. To make it not animate:
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:0];
[tableView noteHeightOfRowsWithIndexesChanged:indexSet];
[NSAnimationContext endGrouping];
PS:与堆栈溢出相比,我对 Apple Dev Forums 上发布的问题的回应更多.
PS: I respond more to questions posted on the Apple Dev Forums than stack overflow.
PSS:我写了基于 NSTableView 的视图
PSS: I wrote the view based NSTableView
这篇关于基于视图的 NSTableView 具有动态高度的行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!