Cocoa 基于视图的NSTableView

Cocoa 基于视图的NSTableView,cocoa,nstableview,Cocoa,Nstableview,我一直在拼命想弄明白tableView:heightOfRow:我想我需要帮助。我想为行内的textView执行动态行高,但似乎无法控制该方法。我已经读了所有我能找到的东西,其实并不多。我可以使用此方法将行的大小设置为我想要的大小,但前提是调整表的大小。不在视图中的行的大小将不会正确调整,直到它们可见并调整表的大小 我添加了tableView:didAddRowView:forRow方法,使用相同的基本思想,它最终将行大小压缩为一行。与tableView:heightOfRow:完全不同,即使是

我一直在拼命想弄明白tableView:heightOfRow:我想我需要帮助。我想为行内的textView执行动态行高,但似乎无法控制该方法。我已经读了所有我能找到的东西,其实并不多。我可以使用此方法将行的大小设置为我想要的大小,但前提是调整表的大小。不在视图中的行的大小将不会正确调整,直到它们可见并调整表的大小

我添加了tableView:didAddRowView:forRow方法,使用相同的基本思想,它最终将行大小压缩为一行。与tableView:heightOfRow:完全不同,即使是相同的代码。我猜设置textView边界的tableView:didAddRowView:forRow方法正在以某种方式进行缩放

以下是我的(希望相关)代码:

-(CGFloat)表视图:(NSTableView*)电视高度(NSInteger)行{
if(tv==dataTableView){
NSInteger valueCol=[tv columnWithIdentifier:@“value”];
NSTableCellView*valueView=[tv viewAtColumn:valueCol row:row MAKEIFESTABLE:NO];
如果(valueView){
//处理感兴趣的列,该行可见
NSRect bounds=[[valueView textField]bounds];
id值=[[valueView textField]stringValue];
NSFont*fieldFont=[[valueView textField]font];
CGFloat Adjusted Height=[value heightForWidth:bounds.size.width font:fieldFont];
CGFloat rowHeight=[tv rowHeight];

如果(adjustedHeight来自您的代码,我猜您希望根据文本字段单元格中的行数更改行高,对吗?因此,如果调整列或表的大小,或者输入新文本,高度应该更改

在我看来,您不需要在-tableView:didAddRowViewForRow中执行任何操作:现在太晚了,行视图应该已经有了它的最终高度。尝试修改视图框架可能会导致错误的异常。因为您的文本字段位于NSTableCellView中(假设有适当的布局约束,默认的应该可以),根据IB中的设计和-tableView:heigthOfRow:

-tableView:heigthOfRow:确实是您需要确定行高的方法。但是您需要为调用to方法的所有行返回一个适当的值,否则在滚动期间,当它们进入可见的矩形时,行将不会显示在正确的高度。因此,我会为viewAtColumn的makeIfEssential:参数选择“是”方法

然后,您需要让表在必要时更新行高(调整列、视图的大小,可能输入新文本…)。这可以在-tableViewColumnDidResize(使用userinfo字典获得调整大小的列)或编辑文本字段时完成。 在这里,您需要在表视图上调用-noteHeightOfRowsWithIndexChanged:。如果调整了列的大小,您可以为所有行调用它,-tableView:heigthOfRow:将返回所有高度。如果编辑了文本字段,您可能只想为其行调用它(但即使为所有行调用该方法也可以)


我希望这会有所帮助。

你能澄清你的疑问和/或问题吗?我无法让任何事情按预期进行。tableView:didAddRowView方法试图将rowView修改为正确的高度,但结果只是在一行高度内被压扁。你是否使用GUI的自动布局约束?嗯,是的,我认为基于multiple认为它可以放在IB中。我对下面的代码做了很多工作,但它仍然有多个小故障。
- (CGFloat)tableView:(NSTableView *)tv heightOfRow:(NSInteger)row {
    if (tv == dataTableView) {
        NSInteger valueCol = [tv columnWithIdentifier:@"value"];
        NSTableCellView *valueView = [tv viewAtColumn:valueCol row:row makeIfNecessary:NO];

        if (valueView) {
            // Working on the interesting column and this row is visible
            NSRect bounds = [[valueView textField] bounds];
            id value = [[valueView textField] stringValue];

            NSFont *fieldFont = [[valueView textField] font];
            CGFloat adjustedHeight = [value heightForWidth:bounds.size.width font:fieldFont];
            CGFloat rowHeight = [tv rowHeight];
            if (adjustedHeight <= rowHeight) adjustedHeight = rowHeight;

            return adjustedHeight;
        }
    }
    return [tv rowHeight];
}


- (void)tableView:(NSTableView *)tv didAddRowView:(NSTableRowView *)rowView forRow:(NSInteger)row {
    if (tv == dataTableView) {
        NSInteger valueCol = [tv columnWithIdentifier:@"value"];
        NSTableCellView *colView = [rowView viewAtColumn:valueCol];
        NSRect textFieldViewBounds = [[colView textField] bounds];
        NSTextField *colTextField = [colView textField];
        NSFont *colFont = [colTextField font];
        id value = [colTextField stringValue];
        CGFloat newHeight = [value heightForWidth:textFieldViewBounds.size.width font:colFont];
        NSSize colViewSize = colView.bounds.size;
        colViewSize.height = newHeight;
        textFieldViewBounds.size.height = newHeight;
        [colTextField setBounds:textFieldViewBounds];
    }
}
- (CGFloat)tableView:(NSTableView *)tv heightOfRow:(NSInteger)row {
    if (tv == dataTableView) {
        NSInteger valueCol = [tv columnWithIdentifier:@"value"];
        NSTableCellView *valueView = [tv viewAtColumn:valueCol row:row makeIfNecessary:NO];

        if (valueView) {
            // Working on the interesting column
            NSRect bounds = [[valueView textField] bounds];
            id value = [[valueView textField] stringValue];

            NSFont *fieldFont = [[valueView textField] font];
            CGFloat adjustedHeight = [value heightForWidth:bounds.size.width font:fieldFont];
            CGFloat rowHeight = [tv rowHeight];
            if (adjustedHeight <= rowHeight) adjustedHeight = rowHeight;

            return adjustedHeight;
        }
    }
    return [tv rowHeight];
}


- (void) tableView:(NSTableView *)tv didAddRowView:(NSTableRowView *)rowView forRow:(NSInteger)row {
    if (tv == dataTableView) {
        [dataTableView noteHeightOfRowsWithIndexesChanged:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(row, 1)]];
    }
}