I did much search on the web and found no answer. The only clue to my question is that I have use another "template" tableview that is identical to the inner tableview.
Finally I devised a working solution, I posted here for the purpose of helping others who may have the same/similar problem.
Note there is a little trick about calculating the actually row height - you have to include height of the template tableview's header view.
func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
if tableView is DetailsTableView { return tableView.rowHeight }
if let rowHeight = rowHeights[row] { return rowHeight }
let item = categorizedItems[row]
if sizingTableView == nil {
var objects: NSArray!
detailsNib!.instantiate(withOwner: nil, topLevelObjects: &objects)
for object in objects {
if let sizingCellView = object as? DetailsCellView {
sizingTableView = sizingCellView.tableView
sizingTableView.delegate = self
sizingTableView.dataSource = self
sizingTableView.isHidden = true
sizingTableView.enclosingScrollView?.setFrameSize(NSSize.zero)
self.view.addSubview(sizingTableView)
break
}
}
}
print("<", sizingTableView.bounds.height)
sizingTableView.row = row
sizingTableView.files = item.files
sizingTableView.reloadData()
print(">", sizingTableView.bounds.height)
var rowHeight = sizingTableView.bounds.height
+ (sizingTableView.headerView?.bounds.height ?? 0.0)
+ summaryTableView.intercellSpacing.height
rowHeights[row] = rowHeight
if rowHeight > MaxRowHeight {
let trailingHeight = (sizingTableView.bounds.height / Double(item.files.count)) * Double(TrailingRowCount)
if rowHeight - MaxRowHeight < trailingHeight {
// Try reserve height for some rows to let scrollbar look more natural.
rowHeight = max(0, MaxRowHeight - trailingHeight)
} else {
rowHeight = MaxRowHeight
}
}
return max(rowHeight, summaryTableView.rowHeight)
}