UITableView滚动到底部以查看插入动画

时间:2010-09-30 02:41:05

标签: iphone uitableview

我有一个UITableView,我在动画中添加一行(使用insertRowsAtIndexPaths:withRowAnimation:)。只要表格不长于屏幕,这一切都很好。

如果它比屏幕大,那么我试图滚动到底部,但它不是我想要的工作。如果我在添加后滚动到新行,我会错过动画。如果我尝试在添加之前滚动到该indexPath,它会抛出异常(关于它不是有效的indexPath)

除了添加空白行之外,还有解决方法吗?

7 个答案:

答案 0 :(得分:22)

是的,有一个没有添加空行的解决方案。

注意:在代码中,我认为只有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];   
}

答案 1 :(得分: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]代码中。如果你这样做将无法正常工作。

尝试一下,它应该在滚动到它们的同时从底部为新行设置动画。

答案 2 :(得分:6)

其他技术,包括在这个问题下提到的那些技术对我来说不起作用。但这确实如此:

  1. 将新项添加到内部dataSource集合。
  2. 在项目中设置一个标志,表示它是“新”。设置此标志时,强制显示单元格以显示任何内容。
  3. 立即拨打 tableView:reloadData:
  4. 现在新项目在此表中,但在视觉上显示为空(由于标志)。
  5. 使用 tableView.indexPathsForVisibleRows检查此新项目是否可见。
  6. 如果项目在屏幕上,请立即将dataSource项目上的“new”标志翻转为NO,并使用动画集调用 tableView:reloadRowsAtIndexPaths 。现在看起来好像刚刚添加了这个项目。 (你在这种情况下完成了)
  7. 如果它不在屏幕上,请使用tableView滚动到视图中:scrollToRowAtIndexPath:但不要立即调用reloadRowsAtIndexPath ...
  8. 处理消息(void) scrollViewDidEndScrollingAnimation :并从步骤6执行相同的reloadRowsAtIndexPath。我怀疑在滚动发生时调用此方法,因此您必须检测从第7步调用它的时间当它被调用时,因为用户正在滚动。
  9. 当我第一次开始iOS开发时,我使用了这种技术(并写了这个答案),但这确实可以长期使用。

答案 3 :(得分:3)

请记住在主线程中执行此操作,否则它将无法滚动到所需位置。

答案 4 :(得分: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];

答案 5 :(得分:1)

这对我有用。我只是突出显示它(通过将其淡出来)而不是插入一行。但原则是相同的。

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)

    })

}

答案 6 :(得分:1)

  1. 更新数据源
  2. 在底部插入行
  3. 滚动到底部
  4. 示例:

    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)