2012-11-07 118 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:將返回所有高度。如果文本字段被編輯,您可能只想調用它的行(但即使調用所有行的方法也應該這樣做)。

我希望它有幫助。

相關問題