NSTableView (view-based) with auto layout grows, but does not shrink rows

I have a NSTableView in view-based (not cell-based) mode with usesAutomaticRowHeights=YES. The rows have dynamic height that might change interactively at any time.

This setup successfully grows table view rows (row content is never clipped). But unfortunately, table view rows don't shrink to the intrinsic row view height, when row views get shorter.

Calling noteHeightOfRowsWithIndexesChanged: on the table view after layout does not seem to fix the problem, my tableView:heightOfRow: is also not called again after noteHeightOfRowsWithIndexesChanged:.

Is there anything I have missed/isn't documented about using auto layout in NSView-based tableviews with variable row height? After all, growing rows works out of the box without any additional code, they just do not shrink on their own to fit the row view.

Thanks in advance for any feedback!

Accepted Reply

After debugging the default table view layout for a long time, I finally found the issue. The table view row views come with some autoresizingmask settings that interfere with content, when using autolayout for the row content views. You need to set the row view's translatesAutoresizingMaskIntoConstraints to NO. This can be achieved for a view-based NSTableView using the delegate method tableView:(NSTableView *)tableView didAddRowView:(NSTableRowView *)rowView forRow:(NSInteger)row:

- (void)tableView:(NSTableView *)tableView didAddRowView:(NSTableRowView *)rowView forRow:(NSInteger)row
{   
    // Remember that rowView != row content view!
    [rowView setTranslatesAutoresizingMaskIntoConstraints:NO];   // Disable constraints interfering with row view content
}
  • Interestingly, this does not seem to be an issue if content does not shrink past the initial row height or maximum row height it has grown to, due to dynamic height increases.

Add a Comment

Replies

Could you show the code that deals with cells ?

After debugging the default table view layout for a long time, I finally found the issue. The table view row views come with some autoresizingmask settings that interfere with content, when using autolayout for the row content views. You need to set the row view's translatesAutoresizingMaskIntoConstraints to NO. This can be achieved for a view-based NSTableView using the delegate method tableView:(NSTableView *)tableView didAddRowView:(NSTableRowView *)rowView forRow:(NSInteger)row:

- (void)tableView:(NSTableView *)tableView didAddRowView:(NSTableRowView *)rowView forRow:(NSInteger)row
{   
    // Remember that rowView != row content view!
    [rowView setTranslatesAutoresizingMaskIntoConstraints:NO];   // Disable constraints interfering with row view content
}
  • Interestingly, this does not seem to be an issue if content does not shrink past the initial row height or maximum row height it has grown to, due to dynamic height increases.

Add a Comment