如何提高包含大量小图像的 UCollectionView 的性能?

2024-05-19

在我的 iOS 应用程序中我有UICollectionView显示大约 1200 个小(35x35 点)图像。图像存储在应用程序包中。

我正确地重用了UICollectionViewCell但仍然存在性能问题,具体取决于我处理图像加载的方式:

  • 我的应用程序是应用程序扩展,它们的内存有限(在本例中为 40 MB)。将所有 1200 个图像放入 Assets 目录并使用加载它们UIImage(named: "imageName")导致内存崩溃 - 系统缓存的图像填满了内存。在某些时候,应用程序需要分配更大的内存部分,但由于缓存的图像,这些内存不可用。操作系统没有触发内存警告并清理缓存,而是杀死了应用程序。

  • 我改变了方法以避免图像缓存。我将图像作为 png 文件放入我的项目(而不是资产目录)中,然后使用加载它们NSBundle.mainBundle().pathForResource("imageName", ofType: "png")现在。该应用程序不再因内存错误而崩溃,但加载单个图像需要更长的时间,即使在最新的 iPhone 上,快速滚动也会出现滞后。

我可以完全控制图像,并且可以将它们转换为 .jpeg 或优化它们(我已经尝试过图像优化 https://imageoptim.com以及其他一些没有成功的选项)。

如何同时解决这两个性能问题?


EDIT 1:

我还尝试在后台线程中加载图像。这是我的子类的代码UICollectionViewCell:

private func loadImageNamed(name: String) {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { [weak self] () in
        let image = bundle.pathForResource(name, ofType: "png")?.CGImage
        if name == self?.displayedImageName {
            dispatch_async(dispatch_get_main_queue(), {
                if name == self?.displayedImageName {
                    self?.contentView.layer.contents = image
                }
            })
        }
    })
}

这使得滚动平滑,而不消耗额外的内存进行缓存but当以编程方式滚动到某个位置时(例如当UICollectionView滚动到顶部)这会导致另一个问题:在滚动动画期间,图像不会更新(滚动速度太快,无法加载),并且滚动完成后,会在几分之一秒内显示错误的图像 - 然后一个又一个地替换为正确的图像。这在视觉上非常令人不安。


EDIT 2:

我无法将小图像分组为更大的合成图像并按照建议显示这些图像这个答案 https://stackoverflow.com/a/31869978/311865.

理由:

  • 考虑不同的屏幕尺寸和方向。每个应用程序都必须有预先合成的图像,这将使应用程序下载量很大。
  • 小图像可以以不同的顺序显示,其中一些在某些情况下可能会隐藏。我肯定无法为每种可能的组合和顺序预先合成图像。

我可以提出可能可以解决您的问题的替代方法:
考虑将图像块渲染为单个合成图像。如此大的图像应该覆盖应用程序窗口的大小。对于用户来说,它看起来像是小图像的集合,但从技术上讲,它将是大图像的表格。

您当前的布局:

 |      |      |      |
 | cell | cell | cell |  -> cells outside of screen
 |      |      |      |
************************
*|      |      |      |*
*| cell | cell | cell |* -> cells displayed on screen
*|      |      |      |*
*----------------------*
*|      |      |      |* 
*| cell | cell | cell |* -> cells displayed on screen
*|      |      |      |*
*----------------------*
*|      |      |      |*
*| cell | cell | cell |* -> cells displayed on screen
*|      |      |      |*
************************
 |      |      |      |
 | cell | cell | cell |  -> cells outside of screen
 |      |      |      |

建议布局:

 |                    |
 |     cell with      |
 |   composed image   |  -> cell outside of screen
 |                    |
************************
*|                    |*
*|                    |*
*|                    |* 
*|                    |* 
*|     cell with      |*
*|   composed image   |* -> cell displayed on screen
*|                    |*
*|                    |*
*|                    |* 
*|                    |* 
*|                    |*
************************
 |                    |
 |     cell with      |
 |   composed image   |  -> cell outside of screen
 |                    |

理想情况下,如果您预先渲染此类合成图像并在构建时将它们放入项目中,但您也可以在运行时渲染它们。可以肯定的是,第一个变体的工作速度会更快。但无论如何,单个大图像比单独的图像片段花费更少的内存。

如果您可以预渲染它们,请使用 JPEG 格式。在这种情况下,可能是您的第一个解决方案(使用[UIImage imageNamed:]在主线程上)会很好地工作,因为使用的内存更少,布局更简单。

如果您必须在运行时渲染它们,那么您将需要使用当前的解决方案(在后台工作),并且当快速动画发生时您仍然会看到图像错位,但在这种情况下,它将是单个错位(一个图像覆盖窗口框架),所以它应该看起来更好。

如果您需要知道用户点击了什么图像(原始小图像35x35),您可以使用UITapGestureRecognizer附着在细胞上。当识别手势时,您可以使用locationInView:小图像正确指数计算方法

我不能说它 100% 解决你的问题,但尝试是有意义的。

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

如何提高包含大量小图像的 UCollectionView 的性能? 的相关文章

  • 错误域=NSURLErrorDomain代码=-1017“该操作无法

    我刚刚开始 ios 开发 我正在尝试与我的 api 交换数据 当我执行 POST 请求时 一切正常 但当我尝试执行 GET 请求时 出现以下错误 错误域 NSURLErrorDomain代码 1017 该操作无法 完全的 NSURLErro
  • 在 iOS 中擦除绘图

    我正在开发一个绘图应用程序 我有一个UIBezierPath 我用它在touchesMoved中绘制 并将其转换为CGPath 然后在tCGplayer上绘制 这是我的代码 void touchesMoved NSSet touches w
  • 删除 WebView Android 中不需要的空白

    我已经开始使用 WebView 开发应用程序 实际上我正在使用 Webview 加载图像 我喜欢使用该类的内置缩放控件 我可以成功加载图像 但我可以看到一些令人恼火的空白 我找不到删除它的方法 我的图像尺寸为 750 1000 我在下面附上
  • 如何使用 WKWebView 正确实施身份验证质询?

    我正在构建一个网络浏览器 但在网络方面我真的是新手 我想测试下面的代码示例 但我没有现实生活中的示例可以使用 void webView WKWebView webView didReceiveAuthenticationChallenge
  • iOS 中的内存泄漏,AVPlayer 永远不会被释放

    我使用了 AVPlayerDemo 示例苹果文档 https developer apple com library ios samplecode AVPlayerDemo Introduction Intro html并在其上编写了我自己
  • 我如何在 viewDidLoad 中执行 UIView animateWithDuration ? IOS 7

    我在 viewDidAppear 中尝试这个 但我有一秒钟的延迟 我能做什么 在 viewDidLoad 中工作 void viewDidAppear BOOL animated fullRotation CABasicAnimation
  • 如何在不使用 viewWillDisappear 的情况下使 NSTimer 无效/取消初始化?

    var faderTimer NSTimer override func viewDidLoad super viewDidLoad self faderTimer NSTimer scheduledTimerWithTimeInterva
  • 响应式 CSS 图像锚点标签 - 图像地图样式

    我一直在开发一个响应式网站 并且在图像映射方面遇到了一些问题 图像映射似乎不适用于基于百分比的坐标 经过一番谷歌搜索后 我发现了一个 JS 解决方法 http mattstow com experiment responsive image
  • 数组与列表的性能

    假设您需要一个需要频繁迭代的整数列表 数组 我的意思是非常频繁 原因可能有所不同 但可以说它位于大容量处理的最内层循环的核心 一般来说 人们会选择使用列表 List 因为它们的大小具有灵活性 最重要的是 msdn 文档声称列表在内部使用数组
  • iOS推送通知:当应用程序处于后台时,如何检测用户是否点击了通知?

    关于这个主题有很多 stackoverflow 线程 但我仍然没有找到好的解决方案 如果应用程序不在后台 我可以检查launchOptions UIApplicationLaunchOptionsRemoteNotificationKey
  • 如何在 UIAlertView (iOS) 中的其他两个按钮(堆叠)之间添加取消按钮

    我正在尝试创建一个带有三个按钮 将堆叠 的 UIAlertView 我希望 取消 按钮位于其他两个按钮之间的中间 我尝试将 cancelButtonIndex 设置为 1 但如果还有其他两个按钮 它只会将它们放置在索引 0 和 1 处 我知
  • iOS 相互认证

    我正在尝试在 IOS 5 中实现相互身份验证 但遇到了麻烦 NSUnderlyingError Error Domain kCFErrorDomainCFNetwork Code 1200 An SSL error has occurred
  • 在完成块中保留循环

    在我的课堂上 我创建了这个方法 void refreshDatasourceWithSuccess CreateDataSourceSuccessBlock successBlock failure CreateDataSourceFail
  • TestFlight 提供反馈按钮

    我正在使用 iOS 8 的最新 testflight 版本 我将自己添加为内部测试人员 现在当我使用 testflight 打开应用程序时 我找不到反馈按钮 如果有人有任何线索 请告诉我 您在 Testflight 应用程序中提供反馈 打开
  • Java元数据读写

    是否可以以通用方式 对于所有图像类型 在 Java 中读取和写入元数据 我找到了一些示例 但它们总是特定的 例如 JPEG 或 PNG 我需要一些足够通用的东西 而不是到处都有 if else 语句 我不想重写源代码 但这是一个很好的例子
  • UILocalNotification 在后台 10 分钟后不提示

    In didFinishLaunchingWithOptions调用函数的定时器循环httpRequest每 1 分钟间隔一次 BOOL application UIApplication application didFinishLaun
  • NSCFData isRessized 崩溃?

    我目前在控制台中收到此崩溃日志 2011 08 23 19 18 40 064 App 1697 707 NSCFData isResizable unrecognized selector sent to instance 0x11f1c
  • PhantomJS 网页内存消耗?

    是否有一种编程方式 因为我想在运行时自动执行 方式来查看网页在通过 PhantomJs 运行时使用了多少内存 我也在使用 casperjs 如果这有帮助的话 我已经搜索了很多但没有找到任何方法 PhantomJs 使用 QtWebKit 因
  • 如何正确创建迦太基 cartfile?

    我正在研究购物车文件 迫不及待地想 简单地创建一个购物车文件 就像所有说明所说的那样 只是 如何 简单地 创建一个 Cartfile 我创建了一个纯文本文档 将其命名为 cartfile 并在其中复制了一些依赖项 Ran carthage
  • Cordova 2.4.0 或 2.5.0 或 2.6.0 和 requirejs

    Cordova 2 4 0 及更高版本支持 AMD 加载到 javascript 中 我特别希望将 Cordova 2 5 0 与最新版本的 RequireJS backbone jquery jquery mobile 一起使用 我还没有

随机推荐