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

2024-03-15

Problem

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

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

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是一个 UICollectionView,由单行项目组成,具有标准流布局并启用水平滚动。
  • 我需要打电话reloadData在滚动之前,因为有可能_items自 UICollectionView 上次显示以来已发生更改。
  • 该问题仅发生在动画滚动时;如果我通过animated:NO然后一切都按预期进行。
  • 当问题发生时,滚动后调用indexPathsForVisibleItems揭示了 UICollectionView认为目标项目不可见.

有什么想法为什么有时会默默地滚动到某个项目失败吗?


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


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

发生了什么

问题似乎是紧随其后[collectionView reloadData] or [collectionView insertItemsAtIndexPaths: @[newItemIndexPath]], 集合视图的内容大小尚未更新.

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

A fix

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

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当它完成更新内容矩形时可以调用回调。 UIKit 对于对其模型执行异步更新的其他方法具有这种风格的回调。例如,一个完成块UIViewController过渡和UIView动画。

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

还有什么要知道的吗?

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

UICollectionView 中的动画滚动到项目并不总是有效 的相关文章

  • 如何在应用程序项目中使用 Cocoa Touch 框架

    我熟悉构建单个 iOS 应用程序 但我坚持使用 Cocoa Touch 框架向多个应用程序共享通用代码 问题 框架的头文件不可见 无法链接到消费应用程序项目 我做了什么 1 我创建了一个名为 libTestFramework 的项目 Coc
  • iPhone SQLite页面缓存不断增长

    I use sqlite数据库用于存储 还有许多数据库事务 我的问题是 sqlite 页面缓存的内存使用量快速增长 在instruments我可以找到这条线 Graph Category Live Bytes Living Transien
  • IDFA 使用不当,您的应用不遵守 ios 中的限制广告跟踪设置

    I have checked the iTC settings I have uploaded the same app 2 days ago and it works fine but when today I uploaded the
  • 在所有浏览器中启用我的网站的平滑滚动

    我正在开发一个视差滚动网站Stellar http markdalgleish com projects stellar js and Skrollr https github com Prinzhorn skrollr图书馆 该网站在 F
  • 在 UITextView 中获取 HTML

    我在中显示htmlUITextView by self textView setValue b Content b forKey contentToHTMLString 编辑内容后UITextView 我想获取包含 html 的内容 所以我
  • 如何组合两个 SwiftyJSON 对象

    我有一个 swiftyJSON 对象 例如 location http img http commentCount 0 timestamp 1432460217550 我希望能够向其附加另一个 swiftyJSON 对象 使其看起来像 lo
  • 使用自动布局、IB 和字体大小时表头视图高度错误

    我正在尝试为我的 uiTableView 创建一个标题视图 不是节标题 我已经有了 我已经在界面生成器中设置了一个 XIB 所有的连接都已连接好并且运行良好 除了桌子没有给它足够的空间 我的问题是表格顶部与表格标题有一点重叠 我的 XIB
  • 保存来自 TrueDepth 相机的深度图像

    我正在尝试保存 iPhone X TrueDepth 相机的深度图像 使用AVCam照片滤镜 https developer apple com library content samplecode AVCamPhotoFilter Lis
  • NSURLCache 不缓存

    我正在使用 Xcode 6 1 6A1030 iOS7 和 iOS8 模拟器 NSURLCache 似乎没有缓存任何东西 我使用 Cache Control 标头 我的服务器返回带有 max age 6000 的 Cache Control
  • iOS 如何触发视频退出全屏后继续播放?

    我正在构建一个在 iOS 中播放视频的网站 我有一个在 iOS 中工作的全屏按钮 但是退出全屏时视频会暂停 有谁知道一种方法可以强制视频在退出全屏时继续播放 或者如何设置一个侦听器来触发视频在退出全屏时自动播放 这是我的代码
  • 访问 google reader 的 Endpoints API 时出错

    我正在尝试在iPhone APP中实现google reader 到目前为止我已经成功收到了sid and auth 当我尝试使用以下命令调用 Endpoints API 时 问题就出现了GET 这是代码 ASIHTTPRequest re
  • 如何检索 iPhone 的区域设置

    我用谷歌搜索过它 但令我有点惊讶的是我找不到它 我只想访问设备配置的区域设置 我试图找到如何列出所有系统属性 以防我能在那里找到区域设置 但甚至找不到如何做到这一点 我知道 认为 我之前检索过系统属性 但我也记得在谷歌搜索时找到该信息并不容
  • 为arm64或arm7s编译OpenSSL FIPS功能库时出现未知的cpu类型

    我可以成功 至少没有警告并生成 a 文件 针对 arm7 x86 64 和 i386 进行编译 当我编译arm64时 我得到Unknown cpu type 100000c no adjustments made 当我编译arm7s时 我得
  • TTTAttributedLabel 可点击截断标记

    我有一个 TTTAttributedLabel 并为其指定了一个自定义属性截断标记 NSAttributedString atributedTruncationToken NSAttributedString alloc initWithS
  • 使用 ZBarSDK 时 iPhone 相机失去自动对焦功能

    我正在开发一个应用程序 用户可以选择是否要扫描条形码或拍摄某物的照片 为了拍照 我正在使用UIImagePickerController照常 为了扫描条形码 我使用 ZbarSDK 1 2ZBarReaderViewController 拍
  • cameraOverlayView 防止使用 allowedEditing 进行编辑

    在我的应用程序中 使用以下行在拍摄照片后对其进行编辑 移动和缩放 效果很好 imagePicker setAllowsEditing YES 但如果我还使用cameraOverlayView 则编辑模式将不再起作用 屏幕出现 但平移和捏合手
  • 检查 Objective-C 块类型?

    这主要是出于好奇 我不太确定它的实际用途是什么 但就这样吧 由于块也是 Objective C 对象 是否可以检查它们的类型 也就是说 它是否响应isKindOfClass 消息以及如何使用该消息来处理块 我天真的以为事情大概是这样的 vo
  • 无需越狱即可检测iOS9上哪个应用程序处于前台

    我正在尝试记录用户在 iOS9 上的个人应用程序使用情况 我宁愿它不会使用越狱有限的解决方案 不言自明 在越狱手机上执行此应用程序的变体应该不难 https www andyibanez com create mobilesubstrate
  • 下载进度条在 iOS 企业发行版中没有改变进度

    我正在通过企业分发开发和分发 iPad 应用程序 它们下载并执行良好 因此一切正常 Web 链接 ipa 文件 plist 文件 配置 问题 是 当用户单击链接进行下载时 iPad 中显示下载进度的进度条显示 正在等待 但却是空的并且永远不
  • 如何将自定义 C 代码放入 SwiftPM 包中?

    我正在尝试将 C 代码打包到 Swift 模块中 我们称之为CModule 一旦我将其放入项目的基本文件夹中 Swift模块 并配置了搜索路径 我可以在 Swift 文件中自动完成工作 并检测错误 警告 问题是 导入时它无法识别该模块 并且

随机推荐