正确调整基于视图的NSTableView上的行的大小

adi*_*dib 9 macos cocoa objective-c nstableview appkit

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];
    }
}
Run Code Online (Sandbox Code Playgroud)

以下是上面发布的通知的处理程序,其中可见行的大小调整:

-(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];   
}
Run Code Online (Sandbox Code Playgroud)

调整所有行大小的替代实现如下所示:

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

注意:此问题与基于视图的NSTableView有些相关,其中行具有动态高度,但更侧重于响应表视图的大小更改.

小智 12

我刚刚解决了这个问题.我所做的是监视滚动视图的内容视图的NSViewBoundsDidChangeNotification

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollViewContentBoundsDidChange:) name:NSViewBoundsDidChangeNotification object:self.scrollView.contentView];
Run Code Online (Sandbox Code Playgroud)

并在处理程序中,获取可见行并调用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];
}
Run Code Online (Sandbox Code Playgroud)

这必须快速执行,因此桌子滚动得很好,但它对我来说非常好.