Problem
I'd like to make a UICollectionView do an animated scroll to a specific item.
This works most of the time, but occasionally the item that I'm trying to scroll to doesn't end up being shown.
Code
- (void)onClick {
// (Possibly recompute the _items array.)
NSInteger target_idx = // (...some valid index of _items)
NSIndexPath *item_idx = [NSIndexPath indexPathForItem:target_idx inSection:0];
[self scrollToItem:item_idx];
}
- (void)scrollToItem:(NSIndexPath*)item_idx {
// Make sure our view is up-to-date with the data we want to show.
NSInteger num_items = [self.collection_view numberOfItemsInSection:0];
if (num_items != _items.count) {
[self.collection_view reloadData];
}
[self.collection_view
scrollToItemAtIndexPath:item_idx
atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally
animated:YES];
}
Details
self.collection_view
is a UICollectionView that consists of a single row of items, with a standard flow layout and horizontal scrolling enabled.- I need to call
reloadData
before scrolling, because it's possible that_items
has changed since the UICollectionView last displayed it. - The problem only happens with animated scrolling; if I pass
animated:NO
then everything works as expected. - When the problem happens, a post-scroll call to
indexPathsForVisibleItems
reveals that the UICollectionView doesn't think that the target item is visible.
Any ideas why scrolling to an item silently fails sometimes?
Update: the problem seems to come from reloading and scrolling in quick succession; if there is no reload, scrolling behaves as expected. Are there any idioms for scrolling to an item after loading new data?