gpt4 book ai didi

ios - UICollectionView 中的动画滚动到项目并不总是有效

转载 作者:可可西里 更新时间:2023-11-01 05:03:19 24 4
gpt4 key购买 nike

问题

我想让 UICollectionView 对特定项目进行动画滚动。

这在大多数情况下都有效,但偶尔我尝试滚动到的项目最终没有显示

代码

- (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,因为自从 UICollectionView 上次显示它以来 _items 可能已经更改。
  • 问题只发生在动画滚动时;如果我传递 animated:NO 那么一切都会按预期进行。
  • 当问题发生时,对 indexPathsForVisibleItems 的滚动后调用显示 UICollectionView 认为目标项目不可见

知道为什么滚动到某个项目有时会静默失败吗?


更新:问题似乎来自快速连续的重新加载和滚动;如果没有重新加载,滚动将按预期运行。加载新数据后滚动到项目是否有任何习惯用法?

最佳答案

在将项目添加到 UICollectionView 后,我遇到了类似/相同的问题。

发生了什么

问题似乎是紧跟在 [collectionView reloadData][collectionView insertItemsAtIndexPaths: @[newItemIndexPath]] 之后, Collection View 的内容大小不是尚未更新

如果您随后尝试滚动添加的项目可见,它将失败,因为内容矩形尚未包含新项目的空间

修复

有一个简单且相当可靠的解决方法,就是将滚动事件发布到运行循环的下一次迭代,如下所示:

const NSUInteger newIndex = 
[self collectionView: self.collectionView numberOfItemsInSection: 0] - 1;

NSIndexPath *const newPath =
[NSIndexPath indexPathForItem: newIndex
inSection: 0];

[self.collectionView insertItemsAtIndexPaths: @[newPath]];

UICollectionViewLayoutAttributes *const layoutAttributes =
[self.collectionView layoutAttributesForItemAtIndexPath: newPath];

dispatch_async(dispatch_get_main_queue(), ^{
[self.collectionView scrollRectToVisible: layoutAttributes.frame
animated: YES];
});

没有更好的修复方法吗?

虽然它有效,但这个“在下一个运行循环滴答时发布滚动调用”的恶作剧感觉很老套。

如果 UICollectionView 可以在完成更新内容 rect 时调用回调,那就更好了。 UIKit 为其他执行模型异步更新的方法提供了这种风格的回调。例如,UIViewController 转换和 UIView 动画的完成 block 。

UICollectionView 不提供此回调。据我所知,没有其他简单干净的方法可以找到它何时完成更新。如果没有这个,下一个运行循环滴答是我们更愿意使用的回调 unicorn 的可行马代理。

还有什么要知道的吗?

知道 UITableView 也有这个问题可能很有用。类似的解决方法也应该在那里工作。

关于ios - UICollectionView 中的动画滚动到项目并不总是有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17751985/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com