动画滚动到项UICollectionView并不总是工作 [英] Animated scroll-to-item in UICollectionView doesn't always work
问题描述
我想做出UICollectionView做动画滚动到一个特定的项目。
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.
- (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];
}
详细信息
-
self.collection_view
是由项目的单排的UICollectionView,与标准流布局和水平滚动启用。 - 我需要滚动之前调用
reloadData code>,因为它可能一次显示它的
_items
自从UICollectionView改变 - 该问题只与动画滚动出现;如果我通过
动画:NO
然后一切按预期工作 - 当问题发生,滚动后调用
indexPathsForVisibleItems
显示,UICollectionView的不认为目标项目可见。 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.
Details
任何原因滚动到一个项目的想法默默地有时会失败?
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?
推荐答案
从@NicholasHart一些帮助,我想我明白这个问题。
With some help from @NicholasHart, I think I understand the problem.
尝试 reloadData code>,然后进行动画滚动到一个新的位置是有道理的(并且似乎工作)只要重装将集合大。
Trying to reloadData
and then performing an animated scroll to a new position makes sense (and seems to work) as long as the reload makes the collection bigger.
重装当收缩的收集,但是,对于一个动画滚动的出发点可能不再存在。这使得动画麻烦。
When reloading shrinks the collection, however, the starting point for an animated scroll might not exist anymore. This makes animation troublesome.
例如,如果你开始的观点一直滚动到右侧(让您最右边的项目可见),然后重装,失去一半的项目,目前还不清楚动画的起点应该是什么。试图在这种情况下会导致在任何一个空操作,或跳转到一个非常奇怪的姿势做动画卷轴。
For example, if you start with the view scrolled all the way to the right (so that your rightmost item is visible) and then reload and lose half of your items, it's not clear what the starting point for the animation should be. Trying to do an animated scroll in this situation results in either a no-op or a jump to a very strange position.
一个解决方案,看起来相当好的是只动画,如果集合越来越大:
One solution that looks reasonably good is to only animate if the collection is getting bigger:
- (void)scrollToItem:(NSIndexPath*)item_idx {
// Make sure our view is up-to-date with the data we want to show.
NSInteger old_num_items = [self.collection_view numberOfItemsInSection:0];
NSInteger new_num_items = _items.count;
if (old_num_items != new_num_items) {
[self.collection_view reloadData];
}
// Animating if we're getting smaller doesn't really make sense, and doesn't
// seem to be supported.
BOOL is_expanding = new_num_items >= old_num_items;
[self.collection_view
scrollToItemAtIndexPath:item_idx
atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally
animated:is_expanding];
}
这篇关于动画滚动到项UICollectionView并不总是工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!