我在 NSScrollView 中有一个 NSTableView。NSTableView 的内容是通过绑定到绑定到 CoreData ManagedObjectContext 的 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 委托方法经常被调用(例如手动滚动表格时),并且只有在插入新项目后才真正需要向下滚动,这使得解决方案更加不优雅。
当应用程序处于活动状态和非活动状态时,我是否可以直接挂接到插入过程或 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 的最后一行是在 superview 中可见的最后一行 - 因此是周围的 NSScrollView)。如果是这样,它会向下滚动。如果没有,用户可能会向上滚动以查看表格的某些内容,并且不希望它自动向下滚动。