2010-09-30 139 views
15

我有一個UITableView,我正在用動畫添加一行(使用insertRowsAtIndexPaths:withRowAnimation:)。只要桌子不長於屏幕,這一切都很好。UITableView滾動到底部看到插入動畫

如果它比屏幕大,那麼我想滾動到底部,但它不是我想要的。如果在添加後滾動到新行,我會錯過動畫。如果我試圖在添加之前滾動到indexPath,它會拋出一個異常(關於它不是一個有效的indexPath)

是否有解決方案,而不是添加一個空行?

回答

21

是的,有沒有增加一個空白行的解決方案。

注:在代碼中,我認爲只有1個部分,但有很多行。您也可以修改代碼以管理多個部分。

- (void)theMethodInWhichYouInsertARowInTheTableView 
{ 
    //Add the object in the array which feeds the tableview 
    NSString *newStringObject = @"New Object"; 
    [arrayWhichFeeds addObject:newStringObject]; 

    [myTableView beginUpdates]; 

    NSArray *paths = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:([arrayWhichFeeds count] - 1) inSection:0]]; 
    [myTableView insertRowsAtIndexPaths:paths withRowAnimation:NO]; 

    [myTableView endUpdates]; 
    [myTableView reloadData]; 
    [myTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:([arrayWhichFeeds count] - 1) inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES]; 
} 
+6

的'-insertRowsAtIndexPaths第二個參數:withRowAnimation:'不是'BOOL';它是一個'UITableViewRowAnimation'類型 – user102008 2011-04-27 23:37:34

+3

我仍然沒有看到用這種技術添加動畫。它滾動得很好,但即使我爲withRowAnimation(不是「NO」,但是UITableViewRowAnimationFade)傳遞一個有效值,我也從來沒有看到它發生。這個問題(我認爲)是如何滾動,仍然看到添加動畫(對吧?) – Aardvark 2013-02-01 17:07:15

+0

它工作得很好,如果你使用'UITableViewRowAnimation.Bottom' – zuziaka 2015-11-30 15:33:57

3

記住在主線程中這樣做,否則它不會滾動到所需的位置。

20

我有這個相同的問題。這是我的解決方案。

首先 - 更新您的數據源

二 -

NSIndexPath *path = [NSIndexPath indexPathForRow:([arrayWhichFeeds count] - 1 inSection:0]]; 
NSArray *paths = [NSArray arrayWithObject:path]; 
[myTableView insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationTop]; 
[myTableView scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionBottom animated:YES]; 

*請注意,這不是包裹在[tableView beginUpdades][tableView endUpdates]代碼。如果你這樣做,它不會按需要工作。

試試看,它應該在滾動到它們的同時在底部的新行中設置動畫。

+0

+1注意到這隻適用於未包裹在beginUpdates&endUpdates 。 – ozz 2012-12-05 00:07:08

+0

工程就像一個魅力!我花了數小時試圖弄清楚這一點。謝謝! – Myxtic 2014-06-28 22:05:08

+0

是的,儘管如果我在我的tableview底部插入行,會有點麻煩,然後他們離開屏幕,但否則我會得到正確的動作。關於begin/endUpdates的好處。先試了一下,但沒有成功。 – Fraggle 2014-10-14 02:34:01

1

更一般地,滾動到下:

NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:([self.table numberOfRowsInSection:([self.table numberOfSections] - 1)] - 1) inSection:([self.table numberOfSections] - 1)]; 
[self.table scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES]; 
+0

是的,但滾動到底部不是問題。我需要以新行的插入動畫可見的方式滾動。我相信Applely的答案是正確的解決方案。 – Nathan 2013-01-13 10:14:44

+0

是的,我同意Applely的回答是正確的。但是,如果您不想對錶格的行/部分結構進行假設,同時仍然可以滾動到最後一行,那麼我的scrollToRowAtIndexPath代碼更爲通用,並且與Applely的整體回答結合得很好。 – djskinner 2013-01-14 11:55:44

+0

哦,好吧,我明白你的意思。謝謝! – Nathan 2013-01-15 07:14:47

6

其他技術,包括在這個問題對我來說沒有工作提到的那些。但是,這確實如此:

  1. 將新項目添加到內部dataSource集合。
  2. 在項目中設置一個標誌,指示它是「新」。設置此標誌時,強制顯示單元格不顯示任何內容。
  3. 立即呼叫的tableView:reloadData:
  4. 現在,新產品在此表中,但會在視覺上顯示爲空(由於標誌)。
  5. 使用tableView.indexPathsForVisibleRows檢查此新項是否可見。
  6. 如果該項目在屏幕上立即將dataSource項目上的「新」標誌翻轉爲NO,並調用tableView:reloadRowsAtIndexPaths帶動畫設置。現在它會顯示爲剛剛添加的項目。 (你在這種情況下完成)
  7. 如果它不在屏幕上使用tableView:scrollToRowAtIndexPath將其滾動到視圖中:但不要立即調用reloadRowsAtIndexPath ...
  8. 處理消息(無效)scrollViewDidEndScrollingAnimation:做,從第6步我懷疑這個方法同樣reloadRowsAtIndexPath被稱爲隨時滾動發生,所以你必須以檢測當它從步驟7調用,當它被稱爲是因爲用戶正在滾動。

當我第一次開始iOS開發時,我開發了這個技術(並寫下了這個答案),但是這確實長期有效。

0

這適用於我。不是插入一行,而是突出顯示它(通過淡入淡出)。但原理是相同的。

if let definiteIndexPath = indexPathDelegate.getIndexPath(toDoItem) { 
    UIView.animateWithDuration(0.5, delay: 0, options: UIViewAnimationOptions.CurveEaseInOut, animations: { 

     self.tableView.scrollToRowAtIndexPath(definiteIndexPath, atScrollPosition: .Middle, animated: false) 

     }, completion: { 
      (finished: Bool) -> Void in 

      // Once the scrolling is done fade the text out and back in. 
      UIView.animateWithDuration(5, delay: 1, options: .Repeat | .Autoreverse, animations: { 
       self.tableView.reloadRowsAtIndexPaths([definiteIndexPath], withRowAnimation: UITableViewRowAnimation.Fade) 

       }, completion: nil) 

    }) 

} 
0
  1. 更新數據源
  2. 插入行於底
  3. 滾動至底部

實施例:

YOUR_ARRAY.append("new string")  
tableView.insertRows(at: [IndexPath(row: YOUR_ARRAY.count-1, section: 0)], with: .automatic) 
tableView.scrollToRow(at: IndexPath(row: YOUR_ARRAY.count-1, section: 0), at: UITableViewScrollPosition.bottom, animated: true)