2012-11-07 149 views
2

我一直在靠墙敲打我的头,试图想出tableView:heightOfRow的理解:我想我需要帮助。我想为行内的textView执行动态行高,并且似乎无法处理该方法。我已经阅读了所有我能找到的东西,其实并不多。我可以使用此方法获取行的大小,但只有在调整表的大小时才行。不可见的行将不会被调整大小,直到它们可见并且表被调整大小。基于视图的NSTableView

我添加了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)]]; 
    } 
} 
+0

你能澄清你的疑问和/或问题吗? –

+0

我无法按预期工作。 tableView:didAddRowView方法试图将rowView修改为正确的高度,但它最终会坐在单排高度内。 – user1804777

+0

您是否使用自动布局 - GUI的约束? –

回答

0

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

IMO你不需要在-tableView中做任何事情:didAddRowViewForRow:对于这一点来说已经太晚了,行视图应该已经有了它的最终高度。试图修改视图框架可能会导致错误的例外。由于您的文本字段位于NSTableCellView中(假设适当的布局约束,默认的应该是好的),它应该按照您在IB中的设计以及由-tableView返回的行高显示预期的结果:heigthOfRow:

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

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

我希望它有帮助。

相关问题