-2

I have a NSTableView in view-based mode (not cell-based) with usesAutomaticRowHeights=YES. The rows have dynamic height that might change at any time. This setup successfully grows table view rows (row content is never clipped), but table view rows don't shrink to the intrinsic row view height when rows 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 always works without any additional code, they just do not shrink on their own.

NSTableView* tv = [[NSTableView alloc] init];

[tv setTranslatesAutoresizingMaskIntoConstraints:NO];
[tv setUsesAutomaticRowHeights:YES];     // Use auto layout for row height

NSTableColumn* column = [[NSTableColumn alloc] init];
[tv addTableColumn:column];

// Set table view data source and delegate, rows are then loaded...
user73014
  • 11
  • 5
  • Post a [mre] please. – Willeke Dec 19 '21 at 14:40
  • How do you change the height of the cells? – Willeke Dec 19 '21 at 23:45
  • Autolayout constraints within the row content views. However, the cell height only increases this way, never shrinks – user73014 Dec 20 '21 at 11:16
  • What makes the cells expand and shrink? How can we reproduce the issue? – Willeke Dec 20 '21 at 11:37
  • There is nothing else happening, just a NSView displayed in a table view cell. But the auto layout enabled tabled view just increases row height and does not want to shrink it, even if the intrinsic height of the content row view is less tall than the table view row view – user73014 Dec 21 '21 at 09:37
  • I tried your code but I don't see any isues. Post a [mre] please. – Willeke Dec 21 '21 at 10:02
  • There is nothing more to it, the only important part is `setUsesAutomaticRowHeights:YES`. As-is, the table view does never shrink table view rows once they have grown based on intrinsic content size, even when breaking autolayout constraints . – user73014 Dec 21 '21 at 18:39

1 Answers1

1

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.

user73014
  • 11
  • 5