Swift - AlamofireImage загружает несколько URL-адресов и отображает их в CollectionView

Я хотел бы загрузить несколько URL-адресов из строки в массиве и отображать изображения в collectionView, Мне удается отобразить четыре изображения (4 видимые ячейки на моем экране), и когда я прокручиваю, начинается загрузка двух других изображений.

Я хочу, чтобы эти 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
    }
}

2 ответа

Решение

Проблема в вашем коде -

Вы сказали, что хотите, чтобы эти 6 изображений загружались одновременно, и когда пользователь прокручивает, 5-е и 6-е изображение должно отображаться немедленно. но это не происходит, потому что cellForItemAtIndexPath Функция для 5-й и 6-й ячейки вызывается при прокрутке. это поведение по умолчанию, и вы не можете вызвать его до прокрутки пользователем.

Быстрое решение проблемы -

Скачать все изображения на улице cellForItemAtIndexPath функция, как в любом viewDidLoad или же viewDidAppear путем зацикливания массива игроков, а затем перезагрузите представление коллекции после завершения загрузки последнего.

Постоянное и лучшее решение -

Реализуйте отложенную загрузку и кэширование изображений, используя Heneke или SDWebImage для отображения изображения в ячейках. И использовать prefetch опция в этих библиотеках, чтобы получить изображения, прежде чем они были показаны в ячейках. Чтобы использовать опцию предварительной выборки, вам нужно перебрать массив и передать URL-адреса функциям извлечения и хранения библиотеки и просто загрузить изображение в ячейку в соответствии с синтаксисом этой библиотеки, и оно будет управлять отображением изображения при его загрузке, и вы не нужно беспокоиться об этом.

Когда вы имеете дело с сетевыми вызовами, вы должны обновить интерфейс в главной очереди. Еще один важный момент, который я хотел бы добавить здесь, - Alamofire имеет специальную библиотеку для загрузки / изменения размера изображения. Пожалуйста, посмотрите на библиотеку AlamofireImage

Alamofire.request(url!).responseImage { response in
            if let image = response.result.value {
               DispatchQueue.main.async {
                  cell.playerImage.image = image
                  cell.playerImage.setNeedsLayout()
               }
            }
        }
Другие вопросы по тегам