3 回答

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

TA貢獻(xiàn)1824條經(jīng)驗(yàn) 獲得超6個(gè)贊
根據(jù)Corbin的回答(順便說一句,感謝您對此發(fā)表一些看法):
Swift 3,基于視圖的NSTableView,帶有適用于macOS 10.11(及更高版本)的自動(dòng)布局
我的設(shè)置:我有一個(gè)NSTableCellView使用自動(dòng)版式布局的布局。它包含(除其他元素外)多行NSTextField,最多可包含2行。因此,整個(gè)單元格視圖的高度取決于此文本字段的高度。
我更新告訴表格視圖兩次來更新高度:
1)當(dāng)表格視圖調(diào)整大小時(shí):
func tableViewColumnDidResize(_ notification: Notification) {
let allIndexes = IndexSet(integersIn: 0..<tableView.numberOfRows)
tableView.noteHeightOfRows(withIndexesChanged: allIndexes)
}
2)當(dāng)數(shù)據(jù)模型對象更改時(shí):
tableView.noteHeightOfRows(withIndexesChanged: changedIndexes)
這將導(dǎo)致表格視圖向其委托要求新的行高。
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)和適當(dāng)?shù)膯卧褚晥D標(biāo)識符。然后,我們檢查是否已經(jīng)為此標(biāo)識符創(chuàng)建了視圖。為此,我們必須維護(hù)一個(gè)列表,其中包含每個(gè)標(biāo)識符的單元格視圖:
// We need to keep one cell view (per identifier) around
fileprivate var savedTableCellViews = [String : NSTableCellView]()
如果沒有保存,則需要?jiǎng)?chuàng)建(并緩存)一個(gè)新的。我們使用模型對象更新單元格視圖,并告訴它根據(jù)當(dāng)前表視圖寬度重新布局所有內(nèi)容。fittingSize然后可以將該高度用作新的高度。
- 3 回答
- 0 關(guān)注
- 1166 瀏覽
添加回答
舉報(bào)