1

我在 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)。如果是这样,它会向下滚动。如果没有,用户可能会向上滚动以查看表格的某些内容,并且不希望它自动向下滚动。

4

1 回答 1

0

我认为你应该能够使用 NSManagedObjectContext 通知,NSManagedObjectContextObjectsDidChangeNotification。创建一个自定义 NSTableView 类并为该通知添加一个观察者:

@implementation 自定义表

-(void)awakeFromNib {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollTable:) name:NSManagedObjectContextObjectsDidChangeNotification object:nil];
}

-(void)scrollTable:(NSNotification *) aNote {
    if ([[aNote.userInfo allKeys] containsObject:@"inserted"]) {
        [self scrollRowToVisible:self.numberOfRows -1];
    }else{
        NSLog(@"It was not an insertion");
    }
}
于 2012-09-06T16:23:13.337 回答