具有异步图像加载功能的自定义UICollectionView单元格 [英] Self-sizing UICollectionView cells with async image loading

查看:107
本文介绍了具有异步图像加载功能的自定义UICollectionView单元格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个水平的 UICollectionView ,其中显示了异步加载的图像.单元格的宽度应该适合图像.

I have a horizontal UICollectionView in which I display images that are loaded asynchronously. The cells are supposed to have their width fit the image.

在视图控制器的 viewDidLoad 中,设置估计的单元格大小:

In viewDidLoad of my view controller, I set the estimated cell size:

(collectionView.collectionViewLayout as? UICollectionViewFlowLayout)?.estimatedItemSize = CGSize(width: 400, height: 400)

cellForItem 中,我使用Kingfisher启动下载任务:

In cellForItem, I start the download task using Kingfisher:

cell.imageView.kf.setImage(with: url) { (_, _, _, _) in 
    cell.layoutSubviews()
}

在我的单元格内,我在 layoutSubviews 方法内有以下代码:

Inside my cell, I have the following code inside the layoutSubviews method:

// 326 is the image view's height
// .aspectRatio is a custom extension that returns: size.width / size.height
imageViewWidthConstraint.constant = 326 * image.aspectRatio
layoutIfNeeded()

在情节提要中,我已经正确设置了布局约束,以使 imageViewWidthConstraint 遵守单元格的宽度.

In the storyboard, I have properly setup the layout constraints so that imageViewWidthConstraint is respected for the cell's width.

以下是运行我的应用程序时的结果:

The following is the result when running my app:

如您所见,尽管已加载图像并更新了布局,但单元格的宽度为400.而且,结果是图像被拉伸以填充图像视图.
当我滚动到右侧&然后返回,将这些单元从集合"视图中删除并重新装入,然后正确地进行布局:

As you can see, the cells have a width of 400, although the image was loaded and the layout updated. And, as result, the images are stretched to fill the image view.
When I scroll to the right & then back, the cells are removed from the collection view and loaded back in, and are now properly laid out:

在滚动时,单元格会调整其宽度,有时会调整到正确的宽度,有时会调整到错误的宽度.

While scrolling, the cells adjust their width, sometimes to the correct width, sometimes to the wrong one.

我在做什么错了?

推荐答案

由于您的图片是异步传入的,因此可能需要一些时间来加载.只有将它们加载后,您才能真正知道图像的大小或比例.这意味着对于每个加载的图像,您都需要重新加载"布局.通过简短搜索看起来很有希望.

Since your images come in asynchronously it may take some time to be loaded. Only once they are loaded you can actually know the size or ratio of the image. That means for every image that is loaded you need to "reload" your layout. From a short search this looks promising.

至少通过这种方式,您可能会获得一些动画,否则,当图像开始加载时,您的单元格只会继续跳动.

At least this way you may get some animations, otherwise your cells will just keep jumping when images start to be loaded.

无论如何,我建议您避免这种情况.如果我可以假设的话;您从服务器获取了一些数据,您使用这些数据从服务器使用传递的URL下载图像并将其显示在集合视图中.最好的方法(如果可能)是请求扩展API,以便您也接收图像的尺寸.因此,而不是

In any case I would advise you to avoid this. If I may assume; you are getting some data from server from which you use delivered URLs to download the images and show them on the collection view. The best approach (if possible) is to request that the API is extended so that you receive dimensions of images as well. So instead of

{
    id: 1,
    image: "https://..."
}

您可以拥有

{
    id: 1,
    image: {
        url: "https://...",
        width: 100,
        height: 100
    } 
}

现在,您可以在下载图像之前使用这些值生成宽高比.

You can now use these values to generate aspect ratio width/height before you download the images.

此外,我并没有看到任何使整体看起来不错(没有跳来跳去)的好的解决方案.

Next to that I don't really see any good solution for the whole thing to look nice (without jumping around).

这篇关于具有异步图像加载功能的自定义UICollectionView单元格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆