关于iPhone:UITableView滚动到底部以查看插入动画

UITableView scroll to bottom to see insertion animation

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

如果它大于屏幕,那么我试图滚动到底部,但是我想要的不是很有效。如果添加后滚动到新行,则会错过动画。如果在添加索引路径之前尝试滚动到该索引路径,它将引发异常(关于它不是有效的索引路径)

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


我遇到了同样的问题。这是我的解决方法。

第一-
更新您的数据源

第二个-

1
2
3
4
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];

*请注意,此代码未package在[tableView beginUpdades][tableView endUpdates]代码中。如果这样做,将无法正常工作。

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


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

注意:在代码中,我认为只有1个部分,但有很多行。您也可以修改代码以管理多个部分。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- (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];  
}


其他技术(包括在此问题下提及的技术)对我不起作用。但是,这样做:

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


    请务必在主线程中执行此操作,否则它将不会滚动到所需位置。


  • 更新数据源
  • 在底部插入行
  • 滚动到底部
  • 示例:

    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)

    这对我有用。我没有插入行,而只是突出显示(通过淡入淡出)。但是原理是相同的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    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)

        })

    }

    通常,滚动到底部:

    1
    2
    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];