2

我一直在拼命试图想出对 tableView:heightOfRow: 的理解,我想我需要帮助。我想为行内的 textView 做动态行高,但似乎无法掌握这种方法。我已经阅读了我能找到的所有内容,实际上并不多。我可以使用这种方法来调整行的大小,但前提是要调整表的大小。不在视图中的行在可见并且调整表格大小之前不会正确调整大小。

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

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

- (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)]];
    }
}
4

1 回答 1

0

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

IMO 你不需要在 -tableView:didAddRowViewForRow 中做任何事情:为时已晚,行视图应该已经有它的最终高度。尝试在那里修改视图框架可能会导致错误异常。由于您的文本字段位于 NSTableCellView 中(假设有适当的布局约束,默认设置应该没问题),它应该按预期显示给定您在 IB 中的设计以及 -tableView:heigthOfRow 返回的行高:

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

然后你需要让表格在必要时更新行高(调整列的大小、视图,也许输入新的文本......)。例如,这可以在 -tableViewColumnDidResize 中完成(使用 userinfo 字典来获取调整大小的列)或在编辑文本字段时完成。在那里,您需要在表格视图上调用 -noteHeightOfRowsWithIndexesChanged:。如果调整了列的大小,则为所有行调用它,并且 -tableView:heigthOfRow: 将返回所有高度。如果编辑了文本字段,您可能只想为其行调用它(但即使为所有行调用该方法也应该这样做)。

我希望它有所帮助。

于 2012-12-14T09:27:31.897 回答