基于视图的NSTableView,使行高取决于内容

Dov*_*izu 7 cocoa objective-c interface-builder nstableview xcode5

我需要一点NSTableView和动态行高的帮助

是)我有的:

基于单列视图的NSTableVIew绑定到数组控制器.每个NSTableCellView包含三个子视图:NSImageView,NSTextField(单行)和NSTextField(多行).基本上,这是一个聊天界面,所以你会有一个消息,发件人和头像的列表.

我想要实现的目标:

当文本长于行的最小高度时,行会展开以适合内容.就像iMessage一样,气泡扩展到适合消息.

......这似乎是一件非常自然的事情,但是我在网上找到的所有相关解决方案(参考文献1,参考文献2),其中没有一个对我有用.

Ref 2看起来很奇妙,但这些都不适用于我的应用程序,因为示例项目使用第三方自动布局代码,整个内容是为iOS设计的.参考文献1提供了一个非常有前途的解决方案,用英语写成.我尝试使用解决方案中描述的"虚拟视图"进行设置,但未能正确地更改和测量高度.

这是我的代码tableView:heightOfRow:,_samplingView是虚拟视图,它具有工作约束并且与中的相同tableView.

- (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row
{
    NSTextField *textField;
    NSTextFieldCell *messageCell;
    for (NSView *subview in [_samplingView subviews]) {
        if ([[subview identifier] isEqualToString:@"message"]) {
            textField = (NSTextField*)subview;
            messageCell = ((NSTextField*)subview).cell;
        }
    }
    Message *message = [[_messagesArrayController arrangedObjects] objectAtIndex:row];
    _samplingView.objectValue = message;

    CGFloat width = [[[tableView tableColumns] objectAtIndex:1] width];
    [_samplingView setBounds:NSMakeRect(0, 0, width, CGFLOAT_MAX)];
    [_samplingView display];

    CGFloat optimalHeight = 10 + [messageCell cellSize].height; //messageCell's size stays the same when I change samplingView to try to measure the height
    return optimalHeight;

}
Run Code Online (Sandbox Code Playgroud)

结果:所有行高度保持不变,不知何故,当我更改宽度时_samplingView,它不会重新调整messageCell大小.我认为自动布局会处理这种压缩/扩展,并允许我测量高度.的确,我很困惑.

编辑:供参考,这是我的视图

     +-----------+---------------------------------------------------+
     |           |  NSTextField                                      |
     |NSImageView|  sender                                           |
     |  avatar   +---------------------------------------------------+
     |           |                                                   |
     |           |  NSTextField (multiline)                          |
     +-----------|  message                                          |
     |           |                                                   |
     |           |  (high compression/hugging priority)              |
     |           |  (this view should decide the height of row)      |
     |           |                                                   |
     +-----------+---------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

ste*_*iva 1

noteHeightOfRowsWithIndexesChanged:当samplingView的宽度发生变化时,需要调用tableView的方法。您的“参考文献 1”中提到了此方法。正如该方法的文档中所述:

如果委托实现 tableView:heightOfRow: 此方法立即使用委托提供的行高重新平铺表视图。

对于基于 NSView 的表格,此方法将生成动画。要关闭动画,请创建一个 NSAnimationContext 分组并将持续时间设置为 0。然后调用此方法并结束分组。

表视图缓存了行高。从概念上讲,当您想要更改行高时,必须将高度标记为脏,以便为您指定的行重新调用您已实现的委托方法。没有什么比使用 KVO 来监视所有影响 rowHeight 的 keyPath 的变化的 cocoa-bindings 更好的了,至少默认情况下是这样。