Swift-如何在UICollectionview中滚动期间停止图像更改?

德潘

collectionview用来显示下载的URL标识的图像。这是我的代码:

var urlArray = ["url1", "url2", ..., "urln"]

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
       let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "myCell, for: indexPath) as? MyCell
       cell.objectImageView.downloadedFrom(link: urlArray[indexPath.row], contentMode: UIViewContentMode.scaleAspectFit)
}

这是我的扩展代码,用于异步下载映像:

func downloadedFrom(url: URL, contentMode mode: UIViewContentMode = .scaleAspectFit) {
    contentMode = mode
    URLSession.shared.dataTask(with: url) { data, response, error in
        guard
            let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200,
            let mimeType = response?.mimeType, mimeType.hasPrefix("image"),
            let data = data, error == nil,
            let image = UIImage(data: data)
            else { return }
        DispatchQueue.main.async() {
            self.image = image
        }
        }.resume()
}

func downloadedFrom(link: String, contentMode mode: UIViewContentMode = .scaleAspectFit) {
    guard let url = URL(string: link) else { return }
    downloadedFrom(url: url, contentMode: mode)
}

当我滚动collectionview图像时,每个单元格中的图像都在不断变化。我试着通过设置来解决它imageview,以nil它加载在之前cellForItemAt的方法:

cell.objectImageView.image = nil
cell.objectImageView.downloadedFrom(link: urlArray[indexPath.row], contentMode: UIViewContentMode.scaleAspectFit)

但这是行不通的。如何解决这个问题?

staticVoidMan

设置nil不会完全有帮助。主要是单元重用问题。

图像下载是异步的,这意味着它将在以后的时间完成。
如果您滚动并cell在图像下载完成之前重新使用了a ,它将设置上一个下载调用的图像,从而引起您的连续更改,这肯定是故障的。

您将需要其他信息来跟踪此信息,以便从根本上确定完成的下载任务是用于imageView还是已被重用,在这种情况下,将由另一个下载任务进行设置。

我们可以通过多种方式来执行此操作,但是在下面,我们将检查下载开始时的URL是否与下载完成时的URL相同。

简单的事情如下:

func downloadedFrom(url: URL, contentMode mode: UIViewContentMode = .scaleAspectFit) {
    /*
     1.
     strUniqueIdentifier_Initial will be the url that caused the download to start.
     A copy of this will be accessible in the closure later.

     Also, we bind this to the imageView for case handling in the closure.
     */
    let strUniqueIdentifier_Initial = url.absoluteString
    self.accessibilityLabel = strUniqueIdentifier_Initial

    contentMode = mode
    let dataTask = URLSession.shared.dataTask(with: url) { data, response, error in
        guard
            let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200,
            let mimeType = response?.mimeType, mimeType.hasPrefix("image"),
            let data = data, error == nil,
            let image = UIImage(data: data)
            else { return }

        /*
         2.
         strUniqueIdentifier_Initial is a copy of the url from the start of the function

         strUniqueIdentifier_Current is the url of the current imageView as we use self
          so if the imageView is reused, this method will be called on it again and at
          that time it it's binded url string will be for the latest download call

         If there's mismatch then the imageView was reused
         */
        let strUniqueIdentifier_Current = self.accessibilityLabel
        if strUniqueIdentifier_Initial != strUniqueIdentifier_Current {
            //previous download task so ignore
            return
        }

        DispatchQueue.main.async() {
            self.image = image
        }
    }
    dataTask.resume()
}

您可以优化逻辑以取消先前的下载,但这是解决核心问题的基本方法。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在Swift中创建水平滚动UICollectionView?

如何在Swift中更改UIButton图像

如何通过在Swift中滚动滑块来滚动UICollectionView?

如何在Swift中更改IBAction UIButton的图像?

如何在Swift中使用UISlider更改UIImageView中的图像

如何在 swift 中从 UICollectionView 呈现 activityViewController

Swift:停止滚动条中的图像上下移动

如何在Xcode / Swift中的滚动视图中居中多个图像

如何在 Swift 中让图像自行移动?

如何在Swift中旋转图像?

如何在UICollectionView中更改滚动方向?

Swift:UICollectionView图像加载

如何在 Swift 中的 touchMoved 期间检测新视图?

如何在Swift中避免UITableViewController的UIImageView中的图像大小更改

如何在Swift中更改结构属性

如何在Swift中更改UIImage的颜色

如何在Swift中更改UIBarButtonItem的文本

如何在Swift中更改navigationBar字体?

如何在Swift中更改UIBezierPath的颜色?

如何在Swift中更改PFUser密码?

如何在Swift中更改字体样式

如何在Swift中更改UIBarButtonItem的tintColor?

如何在Swift中更改文字颜色?

如何在UICollectionView Swift中内联播放视频?

Swift-如何在UICollectionView中扩展单元格

如何在 Swift iOS 中更改单选按钮选定的图像和相应的文本

如何在Swift 3的Map Kit中更改选定的大头针图像?

如何在Swift中点击更改自己的按钮图像

如何在滚动Swift时将UICollectionView图层设置为不移动/静态