NSScrollView内にNSTableViewがあります。NSTableViewのコンテンツは、CoreDataManagedObjectContextにバインドされているNSArrayControllerへのバインドを介して提供されます。NSTableViewへの新しい行は、に追加されたばかりで、削除または並べ替えられることはありません。
NSTableView(またはそれぞれNSScrollView)を一番下に固定して、テーブルに追加された新しい行がすぐに表示されるようにしたいと思います。さらに、これは、ユーザーが他の行を確認するために上にスクロールしたときではなく、NSTableViewが下にスクロールされたときに発生します。
私は現在次のコードを使用しています
- (void)tableView:(NSTableView *)tableView didAddRowView:(NSTableRowView *)rowView forRow:(NSInteger)row {
NSInteger numberOfRows = [tableView numberOfRows];
NSLog(@"row: %lu, %lu numberOfRows ", row, numberOfRows);
if (row == numberOfRows-1) {
[tableView scrollRowToVisible:numberOfRows - 1];
}
}
これはこれまでのところ機能しますが、ウィンドウがアクティブなときだけです。ウィンドウが非アクティブの場合、ウィンドウが再びアクティブになるまで、didAddRowViewメソッドは呼び出されません。したがって、NSTableViewはすぐには下にスクロールしません。NSTableViewもCoreDataバインディングを介して入力されるため、新しいアイテムが挿入された後、手動でスクロールをトリガーできるポイントはわかりません。さらに、didAddRowViewデリゲートメソッドは非常に頻繁に呼び出され(たとえば、テーブルを手動でスクロールする場合)、新しいアイテムが挿入された後に下にスクロールする必要があるだけで、ソリューションの洗練度がさらに低下します。
新しい行がNSTableViewに追加されたときに、アプリケーションがアクティブおよび非アクティブのときに、挿入プロセスまたはNSScrollViewに直接フックして、一番下までスクロールできるポイントはありますか?
編集: 完了のため、または@rdelmarのソリューションが機能しない場合に備えて、問題のNSTableViewをサブクラス化し、これをreloadDataメソッドに実装しました。
- (void) reloadData {
[super reloadData];
NSInteger numberOfRows = [self numberOfRows];
NSRange rowsInRect = [self rowsInRect:self.superview.bounds];
NSInteger lastVisibleRow = rowsInRect.location + rowsInRect.length;
if (lastVisibleRow == numberOfRows-1) {
[self scrollRowToVisible:numberOfRows - 1];
}
}
新しいアイテムがArrayControllerで受信されると、reloadDataメソッドが呼び出され、テーブルに追加されます。スーパークラスのreloadDataを呼び出した後、これはTableViewが一番下までスクロールされているかどうかをチェックします(TableViewの最後の行は、スーパービューに表示される最後の行、つまり周囲のNSScrollViewです)。その場合は、下にスクロールします。そうでない場合、ユーザーはテーブルの一部のコンテンツを確認するために上にスクロールし、自動的に下にスクロールすることを望まない可能性があります。