Correctly resizing rows on view
A view-based NSTableView
with rows that have dynamic heights doesn't resize its rows when the table view size is changed. This is a problem when the row height is derived from the table view's width (think text blocks that fills a column and wraps thus extending the row size).
I've been trying to get NSTableView
to resize its rows whenever it changed size but have experienced little success:
enumerateAvailableRowViewsUsingBlock:
, some of the non-visible rows doesn't get resized and thus were shown with the old height when the user scrolls and reveal these rows. Anybody can help?
This is where I detect the table view size change - in the table view's delegate:
- (void)tableViewColumnDidResize:(NSNotification *)aNotification
{
NSTableView* aTableView = aNotification.object;
if (aTableView == self.messagesView) {
// coalesce all column resize notifications into one -- calls messagesViewDidResize: below
NSNotification* repostNotification = [NSNotification notificationWithName:BSMessageViewDidResizeNotification object:self];
[[NSNotificationQueue defaultQueue] enqueueNotification:repostNotification postingStyle:NSPostWhenIdle];
}
}
Whereas the following is the handler of the notification posted above, where the visible rows get resized:
-(void)messagesViewDidResize:(NSNotification *)notification
{
NSTableView* messagesView = self.messagesView;
NSMutableIndexSet* visibleIndexes = [NSMutableIndexSet new];
[messagesView enumerateAvailableRowViewsUsingBlock:^(NSTableRowView *rowView, NSInteger row) {
if (row >= 0) {
[visibleIndexes addIndex:row];
}
}];
[messagesView noteHeightOfRowsWithIndexesChanged:visibleIndexes];
}
The alternative implementation that resizes all rows looks like this:
-(void)messagesViewDidResize:(NSNotification *)notification
{
NSTableView* messagesView = self.messagesView;
NSIndexSet indexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0,messagesView.numberOfRows)];
[messagesView noteHeightOfRowsWithIndexesChanged:indexes];
}
Note: This question is somewhat related to View-based NSTableView with rows that have dynamic heights but is more focused towards responding to the table view's size change.
I just went through this exact problem. What I did was monitor the NSViewBoundsDidChangeNotification for the scroll view's content view
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollViewContentBoundsDidChange:) name:NSViewBoundsDidChangeNotification object:self.scrollView.contentView];
and in the handler, get the visible rows and call noteHeightOfRowsWithIndexesChange:. I disable animation while doing this so the user doesn't see the rows wiggle during the resize as view's come into the table
- (void)scrollViewContentBoundsDidChange:(NSNotification*)notification
{
NSRange visibleRows = [self.tableView rowsInRect:self.scrollView.contentView.bounds];
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:0];
[self.tableView noteHeightOfRowsWithIndexesChanged:[NSIndexSet indexSetWithIndexesInRange:visibleRows]];
[NSAnimationContext endGrouping];
}
This has to perform quickly so the table scrolls nicely but its working very well for me.
链接地址: http://www.djcxy.com/p/49962.html上一篇: Qt编程人员的xaml布局介绍
下一篇: 正确调整视图上的行大小