2014-01-09 24 views
4

向NSTableView添加新行後,我想滾動到該行。如何在動畫完成後滾動到添加到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]; 

我該怎麼做?

回答

1

,我發現他的問題的解決方案,我很高興:

[_tableView insertRowsAtIndexes:indexSet withAnimation:NSTableViewAnimationEffectGap]; 

[[NSOperationQueue mainQueue] addOperationWithBlock:^{ 
    NSUInteger firstIndex = [indexSet firstIndex]; 
    [_tableView scrollRowToVisible:firstIndex]; 
}]; 

我只是延緩滾動請求,直到下一次運行循環。

+2

我試過在最後插入一行後滾動到tableview的底部,它只是滾動到倒數第二行。有任何想法嗎? – rocky

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; 
} 
+0

嗨Wil。在我看來,這些問題源於這樣的事實,即直到執行插入操作後行纔會存在。我嘗試了延遲我的scrollToRow調用0.1秒(使用dispatch_after)並解決了問題。雖然感覺哈克。由於scrollToPoint不是一個已定義的函數,我無法輕鬆測試您的代碼。 – tarmes

+0

哦,我們在我們的clipView子類中添加了animate:參數,沒錯。看起來很奇怪,即使動畫正在進行,插入後不能立即引用該行,但所有這些代碼都非常新。 –