Swift - AlamofireImage 下载多个 URL 并显示在 CollectionView 中

Posted

技术标签:

【中文标题】Swift - AlamofireImage 下载多个 URL 并显示在 CollectionView 中【英文标题】:Swift - AlamofireImage download multiple URLs and display in CollectionView 【发布时间】:2016-11-22 18:33:23 【问题描述】:

我想从数组中的字符串下载多个 URL,并在collectionView 中显示图像。我成功地显示了四个图像(屏幕上的 4 个可见单元格),当我滚动时,开始下载其他 2 个图像。

我希望同时下载这 6 张图片(我不必滚动即可开始其他下载)。在此之后,我想在我的collectionView 中显示下载和显示图像所花费的总时间。

我做错了什么?

这是我的代码:

import UIKit
import AlamofireImage
import Alamofire

class ViewController: UIViewController,UICollectionViewDelegate,UICollectionViewDataSource 

    var players = [
        ["image_Name":"https://images.unsplash.com/photo-1420768255295-e871cbf6eb81?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&s=4b94ef340bd7f6cac580fbc76af326af"],
        ["image_Name":"https://images.unsplash.com/photo-1465411801898-f1a78de00afc?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&s=149d27223217c0fa63c7dd8f1e8d23f6"],
        ["image_Name":"https://images.unsplash.com/photo-1466853817435-05b43fe45b39?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&s=a3b629b7e0c4f710ce119f219ae5b874"],
        ["image_Name":"https://images.unsplash.com/photo-1467404899198-ccadbcd96b91?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&s=66eef8db7a0aa4119c6c8d7ba211f79f"],
        ["image_Name":"https://images.unsplash.com/photo-1470322346096-ecab3914cab7?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&s=83863ba23662871baf6434c6000e00bd"],
        ["image_Name":"https://images.unsplash.com/photo-1473624566182-509e437512f4?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&s=54c3ec6d1fee824d62e6fa76676ddf17"]
    ]
    var methodStart = Date()

    @IBOutlet weak var mycall: UICollectionView!
    var selectedIndex=[Int]()

    override func viewDidLoad() 
        super.viewDidLoad()
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
    


    func numberOfSections(in collectionView: UICollectionView) -> Int 
        return 1
    

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return self.players.count
    

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        let cell:playerCell = collectionView.dequeueReusableCell(withReuseIdentifier: "playerCell", for: indexPath) as! playerCell

        let url = URL(string:self.players[indexPath.row]["image_Name"]!)
        if indexPath.row == 0 
           methodStart = Date()
        
        Alamofire.request(url!).responseImage  response in
            //            debugPrint(response)
            //            print(response.request)
            //            print(response.response)
            //            debugPrint(response.result)

            if let image = response.result.value 
                cell.playerImage.image = image
            
        

        if indexPath.row == self.players.count - 1 
            let methodFinish = NSDate()
            let executionTime = methodFinish.timeIntervalSince(methodStart as Date)
            print("Execution time: \(executionTime)")
        

        return cell
    

【问题讨论】:

下载后,更新主队列中的图片并设置图片的needslayout属性 【参考方案1】:

你的代码有问题 -

您说您希望同时下载这 6 张图片,并且当用户滚动第 5 张和第 6 张图片时应立即显示。但这并没有发生,因为滚动时调用了第 5 和第 6 个单元格的 cellForItemAtIndexPath 函数。这是默认行为,您不能在用户滚动之前调用它。

快速修复解决方案 -

下载cellForItemAtIndexPath函数之外的所有图像,如viewDidLoadviewDidAppear,通过循环播放器数组,然后在完成最后一个下载后重新加载集合视图。

永久的最佳解决方案 -

使用Heneke 或SDWebImage 实现图像的延迟加载和缓存,以在单元格中显示图像。并在这些库中使用prefetch 选项在图像显示在单元格中之前获取图像。要使用预取选项,您需要遍历数组并将 urls 传递给库的获取和存储功能,并根据该库的语法将图像加载到单元格中,它会在下载图像时管理图像的显示,您不用担心这个。

【讨论】:

【参考方案2】:

当您处理网络调用时,您应该更新主队列中的 UI。我想在这里添加的另一个有效点是 Alamofire 有一个用于图像下载/调整大小的特殊库。请看AlamofireImage Library

Alamofire.request(url!).responseImage  response in
            if let image = response.result.value 
               DispatchQueue.main.async 
                  cell.playerImage.image = image
                  cell.playerImage.setNeedsLayout()
               
            
        

【讨论】:

以上是关于Swift - AlamofireImage 下载多个 URL 并显示在 CollectionView 中的主要内容,如果未能解决你的问题,请参考以下文章

Swift 4 中的 AlamofireImage 问题

AlamofireImage:是不是可以从 Swift 中的 NSimageview 获取原始数据?

快速滚动时带有 AlamofireImage 的 Swift UItableview 崩溃

Swift:将数据从 tableView 显示到另一个 ViewController(JSON、Alamorife、AlamofireImage)

AlamofireImage:如何使用 POST 请求下载图像

AlamofireImage 下载到 CoreData