したがって、目標は、挿入されたすべての行が表示されるようにコンテンツを挿入して配置することです。これは、挿入された行がテーブル自体よりも短い限り実行可能です。
スクロールアニメーションと挿入が干渉しているようです。修正するには、まずスクロールを行いましょう。これは、アニメーションが終了したときの明確なフック、つまりデリゲート メソッドがドキュメントで提供されているためです。- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
解決策は次のようになります。
// about to insert cells at arCells index paths
// first scroll so that the top is visible
NSIndexPath *firstNewIndexPath = [arCells objectAtIndex:0];
NSInteger previousRow = MAX(firstNewIndexPath.row-1, 0);
NSIndexPath *previousIndexPath = [NSIndexPath indexPathForRow:previousRow inSection:firstNewIndexPath.section];
// if the new rows are at the bottom, adjust the content inset so the scrolling can happen
if (firstNewIndexPath.row > [self.tableView numberOfRowsInSection:0) {
self.tableView.contentInset = UIEdgeInsetsMake(0, 0, self.tableView.frame.size.height - 80, 0); // 80 is just to illustrate, get a better row height from the table
}
[self.tableView scrollToRowAtIndexPath:previousIndexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
// there may be a better way to setup that scroll, not sure, but that should work.
これで、アニメーションが終了したことを知るためのフックができました。安全に挿入できます...
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
// hopefully you have those arCells in an instance variable already, otherwise
// i think you'll need to create one to save state in between the two animations
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:arCells withRowAnimation:UITableViewRowAnimationLeft];
[self.tableView endUpdates];
// restore the content inset
self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
}
この記事のような他の 2 つのSO 記事では、行のアニメーションが完了したことを知らせるフックを扱っています。その方が良いかもしれません。どこにスクロールすればよいか (あなたの質問が示唆するように、新しく挿入された行の一番下まで) を把握できるからです。しかし、これらのいずれも、アニメーションが完了したことを確実に知らせるものではないようです。