向NSTableView添加新行后,我想滚动到它。
当该行已添加到表的末尾时,滚动仅滚动到之前最后一行的行。我最初认为我必须等待动画完成,但这并没有解决我的问题。这是我的代码:
[NSAnimationContext beginGrouping];
[_tableView insertRowsAtIndexes:indexSet withAnimation:NSTableViewAnimationEffectGap];
[[NSAnimationContext currentContext] setCompletionHandler:^{
// Scroll to the first inserted row
NSUInteger firstIndex = [indexSet firstIndex];
[_tableView scrollRowToVisible:firstIndex];
}];
[NSAnimationContext endGrouping];
我该怎么做?
答案 0 :(得分:2)
我找到了解决他问题的方法,我很满意:
[_tableView insertRowsAtIndexes:indexSet withAnimation:NSTableViewAnimationEffectGap];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
NSUInteger firstIndex = [indexSet firstIndex];
[_tableView scrollRowToVisible:firstIndex];
}];
我只是将滚动请求延迟到下一个运行循环。
答案 1 :(得分:1)
我们遇到了这个问题,所以我们最终在其他动画发生时进行滚动,以便将行保留在屏幕上。您可以在动画分组中调用此代码,您可以在其中执行tableView修改。
代码如下所示:
- (BOOL)scrollRowToVisible:(NSInteger)row animate:(BOOL)animate;
{
LIClipView *const clipView = (id)_sourceListOutlineView.enclosingScrollView.contentView;
const NSRect finalFrameOfRow = [_sourceListOutlineView rectOfRow:row];
const NSRect clipViewBounds = clipView.bounds;
if (NSIsEmptyRect(finalFrameOfRow) || _sourceListOutlineView.numberOfRows <= 1)
return NO;
const NSRect finalFrameOfLastRow = [_sourceListOutlineView rectOfRow:(_sourceListOutlineView.numberOfRows - 1)];
if (NSMaxY(finalFrameOfLastRow) <= NSHeight(clipViewBounds))
// The source list is shrinking to fully fit in its clip view (though it might still be larger while animating); no scrolling is needed.
return NO;
if (NSMinY(finalFrameOfRow) < NSMinY(clipViewBounds)) {
// Scroll top of clipView up to top of row
[clipView scrollToPoint:(NSPoint){0, NSMinY(finalFrameOfRow)} animate:animate];
return YES;
}
if (NSMaxY(finalFrameOfRow) > NSMaxY(clipViewBounds)) {
// Scroll bottom of clipView down to bottom of source, but not such that the top goes off-screen (i.e. repeated calls won't keep scrolling if the row is higher than visibleRect)
[clipView scrollToPoint:(NSPoint){0, MIN(NSMinY(finalFrameOfRow), NSMaxY(finalFrameOfRow) - NSHeight(clipViewBounds))} animate:animate];
return YES;
}
return NO;
}