2012-08-22 82 views
9

具有动态高度的行的基于视图的NSTableView不会在更改表视图大小时调整行的大小。当行高从表视图的宽度派生时(认为填充列和换行从而扩展行大小的文本块),这是一个问题。在基于视图的NSTableView上正确调整行大小行

我一直试图让NSTableView来调整其行,只要改变它的大小,但经历过小的成功:

  • 如果我通过查询enumerateAvailableRowViewsUsingBlock:,一些非可见的行调整仅可见行不会调整大小,因此当用户滚动并显示这些行时,会显示旧高度。
  • 如果我调整所有行的大小,当行数很多时(每个窗口在我的1.8Ghz i7 MacBook Air中调整1000行后大约需要1秒延迟),它会变得非常慢。

有人可以帮忙吗?

这是我发现表视图大小的改变 - 在表视图的委托:

- (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]; 
    } 
} 

而下面是上面贴的通知,其中可见的行得到调整大小的处理程序:

-(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]; 
} 

替代实现,调整大小,所有的行看起来是这样的:

-(void)messagesViewDidResize:(NSNotification *)notification 
{ 
    NSTableView* messagesView = self.messagesView;  
    NSIndexSet indexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0,messagesView.numberOfRows)];  
    [messagesView noteHeightOfRowsWithIndexesChanged:indexes]; 
} 

注意:这个问题与View-based NSTableView with rows that have dynamic heights有些相关,但更注重响应表视图的大小更改。

回答

11

我刚刚经历了这个确切的问题。我所做的就是监控NSViewBoundsDidChangeNotification滚动视图的内容视图

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollViewContentBoundsDidChange:) name:NSViewBoundsDidChangeNotification object:self.scrollView.contentView]; 

并在处理程序,获得可见的列和调用noteHeightOfRowsWithIndexesChange :.我禁用动画,而这样做,因此用户不会看到调整大小时行扭动作为视图的进入表

- (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]; 
} 

这有快速执行得这么好表滚动,但它的工作对我非常好。

+0

对我来说,我一直等到用户完成调整大小,然后重新调整行高。 – adib

+1

显然滚动视图内容视图不会发布更改通知,即使在调用'[self.scrollView.contentView setPostsBoundsChangedNotifications:YES]' – adib

+1

似乎NSViewFrameDidChangNotification更适合实时调整大小 –

相关问题