0

In my table view, I am inserting some rows

[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:arCells withRowAnimation:UITableViewRowAnimationLeft];
[self.tableView endUpdates];
[self.tableView scrollToRowAtIndexPath:[arCells lastObject] atScrollPosition:UITableViewScrollPositionBottom animated:YES];

Iam not getting the animation UITableViewRowAnimationLeft for all the cells. Suppose if Iam inserting 5 rows, I am getting the animation UITableViewRowAnimationLeft for only the first 2 cells, rest of them are inserting without animation. Can anyone tell why this is happening? Did I do anything wrong?

IronManGill
  • 7,222
  • 2
  • 31
  • 52
Dev
  • 3,885
  • 10
  • 39
  • 65
  • just a hunch: can you try commenting out the scrollToRow and see if behaves the same way? – danh Oct 12 '12 at 04:45
  • Yeah, I commented and test. At that time when I am inserting 5 rows after the last cell, the animation I cannot visible. The rows which are visible getting the animation properly. – Dev Oct 12 '12 at 04:50
  • Right, so I think that's the expected behavior. I think the issue is that we're launching two animations together affecting the same stuff. It's a race condition. Let me check docs to see if there's a hook that tells you the insert animation is done, then we can start the scroll – danh Oct 12 '12 at 04:52
  • Oh..Ok.. Thank you danh... The thing which I want is if the rows to be inserted are not visible, then it should move up to make it visible. I need the animation UITableViewRowAnimationLeft. Can you tell is it possible or not? – Dev Oct 12 '12 at 04:56
  • Yes. I think it can be done. Will answer below... – danh Oct 12 '12 at 04:59
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/17907/discussion-between-danh-and-dev) – danh Oct 12 '12 at 05:37

1 Answers1

0

So the goal is to do the insert and position the content in such a way that all of the inserted rows are visible. This is doable as long as the inserted rows are shorter than the table itself.

It seems that the scroll animation and the insertion are interfering with one another. To fix, let's do the scroll first, because the docs provide a clear hook for when that animation finishes, namely, the delegate method - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView

The solution would go something like this:

// 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.

Now we have a hook to know that the animation finished. We can safely do the insert...

- (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);
}

A couple other SO articles like this one deal with getting a hook to tell us the row animation is done. That might be better because then we have a better idea where to scroll to (as your questions suggests, to the bottom of the newly inserted rows). But none of these seem certain to let us know that the animation is done.

Community
  • 1
  • 1
danh
  • 62,181
  • 10
  • 95
  • 136
  • Thinking about this more, I think it needs to work when the new cells are at the very bottom. The scrolling won't do what we want because the new cells aren't there yet. One idea is to use contentInset. Will edit to illustrate. – danh Oct 12 '12 at 05:40