3 回答

TA貢獻1820條經驗 獲得超9個贊
這是雞和雞蛋的問題。表格需要知道行高,因為它確定了給定視圖的位置。但是,您希望視圖已經存在,因此可以使用它來計算行高。那么,哪個先出現?
答案是保留額外的NSTableCellView(或用作“單元格視圖”的任何視圖)周圍,僅用于測量視圖的高度。在tableView:heightOfRow:委托方法中,訪問模型的“行”并設置objectValueon NSTableCellView。然后將視圖的寬度設置為表格的寬度,然后(無論您要執行什么操作)找出該視圖所需的高度。返回該值。
請勿noteHeightOfRowsWithIndexesChanged:在委托方法tableView:heightOfRow:或viewForTableColumn:row:!中調用 那是不好的,并且會引起大麻煩。
要動態更新高度,那么您應該做的是響應文本更改(通過目標/動作)并重新計算該視圖的計算高度?,F在,請勿動態更改NSTableCellView的高度(或任何用作“單元格視圖”的視圖)。該表必須控制該視圖的框架,如果嘗試設置該視圖,您將與之抗爭。相反,在計算高度的文本字段的目標/操作中,調用 noteHeightOfRowsWithIndexesChanged:,這將使表調整該行的大小。假設您已經在子視圖(即的子視圖NSTableCellView)上設置了自動調整大小的蒙版設置,那么應該可以調整大??!如果不是,請首先對子視圖的調整大小蒙版進行操作,以使行高度可變的東西正確無誤。
不要忘記noteHeightOfRowsWithIndexesChanged:默認設置動畫。要使其不動畫,請執行以下操作:
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:0];
[tableView noteHeightOfRowsWithIndexesChanged:indexSet];
[NSAnimationContext endGrouping];
PS:我對Apple Dev論壇上發布的問題的回答要多于堆棧溢出。
PSS:我寫了基于視圖的NSTableView

TA貢獻1824條經驗 獲得超6個贊
根據Corbin的回答(順便說一句,感謝您對此發表一些看法):
Swift 3,基于視圖的NSTableView,帶有適用于macOS 10.11(及更高版本)的自動布局
我的設置:我有一個NSTableCellView使用自動版式布局的布局。它包含(除其他元素外)多行NSTextField,最多可包含2行。因此,整個單元格視圖的高度取決于此文本字段的高度。
我更新告訴表格視圖兩次來更新高度:
1)當表格視圖調整大小時:
func tableViewColumnDidResize(_ notification: Notification) {
let allIndexes = IndexSet(integersIn: 0..<tableView.numberOfRows)
tableView.noteHeightOfRows(withIndexesChanged: allIndexes)
}
2)當數據模型對象更改時:
tableView.noteHeightOfRows(withIndexesChanged: changedIndexes)
這將導致表格視圖向其委托要求新的行高。
func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
// Get data object for this row
let entity = dataChangesController.entities[row]
// Receive the appropriate cell identifier for your model object
let cellViewIdentifier = tableCellViewIdentifier(for: entity)
// We use an implicitly unwrapped optional to crash if we can't create a new cell view
var cellView: NSTableCellView!
// Check if we already have a cell view for this identifier
if let savedView = savedTableCellViews[cellViewIdentifier] {
cellView = savedView
}
// If not, create and cache one
else if let view = tableView.make(withIdentifier: cellViewIdentifier, owner: nil) as? NSTableCellView {
savedTableCellViews[cellViewIdentifier] = view
cellView = view
}
// Set data object
if let entityHandler = cellView as? DataEntityHandler {
entityHandler.update(with: entity)
}
// Layout
cellView.bounds.size.width = tableView.bounds.size.width
cellView.needsLayout = true
cellView.layoutSubtreeIfNeeded()
let height = cellView.fittingSize.height
// Make sure we return at least the table view height
return height > tableView.rowHeight ? height : tableView.rowHeight
}
首先,我們需要獲取模型對象的行(entity)和適當的單元格視圖標識符。然后,我們檢查是否已經為此標識符創建了視圖。為此,我們必須維護一個列表,其中包含每個標識符的單元格視圖:
// We need to keep one cell view (per identifier) around
fileprivate var savedTableCellViews = [String : NSTableCellView]()
如果沒有保存,則需要創建(并緩存)一個新的。我們使用模型對象更新單元格視圖,并告訴它根據當前表視圖寬度重新布局所有內容。fittingSize然后可以將該高度用作新的高度。
- 3 回答
- 0 關注
- 1154 瀏覽
添加回答
舉報