9

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

注:この質問は、動的な高さを持つ行を持つビューベースの NSTableView に多少関連していますが、テーブルビューのサイズ変更への対応により重点を置いています。

4

1 に答える 1

12

私はちょうどこの正確な問題を経験しました。私がしたことは、スクロールビューのコンテンツビューの 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];
}

これはすばやく実行する必要があるため、テーブルはうまくスクロールしますが、私にとっては非常にうまく機能しています。

于 2012-09-05T19:49:21.700 に答える