2010-09-30 112 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)