Анимированные изображения с эффектом затухания в ячейках вида Коллекция - PullRequest
2 голосов
/ 10 июля 2019

Примечание. Я перепробовал все подходящие вопросы из-за переполнения стека, но ни один из них не помог исправить эту проблему / сценарий и, следовательно, опубликовал сообщение.

У меня есть представление коллекции, в котором у меня есть количество ячеек, где каждая ячейка имеет один вид изображения. Каждая ячейка будет иметь различный массив изображений, которые мне нужно показывать одно за другим через эффект затухания. Первый раз это показывает правильно, однако, когда я прокручиваю, то возникают проблемы Изображение первой ячейки отображается в любой другой ячейке. Изображения перемешиваются.


extension ViewController: UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return imagesArray.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath)
//        let image = cell.viewWithTag(1) as! UIImageView
//        let imgArr =  imagesArray[indexPath.row]
//        image.downloadImageAndAnimateIt(imageStringArray: imgArr)
        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let size = self.collectionView.bounds.size.width / 2 - 5
        return CGSize(width: size, height: size - 5)
    }

    func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
        let image = cell.viewWithTag(1) as! UIImageView
        let imgArr =  imagesArray[indexPath.row]
        image.downloadImageAndAnimateIt(imageStringArray: imgArr)

    }


}
//=========== END of view controller

extension UIImageView {

    func downloadImageAndAnimateIt(imageStringArray:[String]){

        var imagesArray = [UIImage]()
        for imgStr in imageStringArray{
            imagesArray.append(UIImage(named: imgStr)!)
        }        

        let dispatchGroup = DispatchGroup()
//        dispatchGroup.notify(queue: DispatchQueue.main) {[weak self] in
//            self?.animationImages = imagesArray.compactMap({$0})
//            self?.animationDuration = 5.0
//            self?.startAnimating()
//        }

        var photoCount = 0        
        var timer = Timer()

        dispatchGroup.notify(queue: DispatchQueue.main) {[weak self] in

            timer = Timer.scheduledTimer(withTimeInterval: 2.0, repeats: true, block: { (timer) in
                if (photoCount < imagesArray.count - 1){
                    photoCount = photoCount + 1;
                }else{
                    photoCount = 0;
                }
                if let this = self {
                    UIView.transition(with: this, duration: 2.0, options: .transitionCrossDissolve, animations: {
                        this.image = imagesArray[photoCount]
                    }, completion: nil)
                }
            })

        }

    }

}

Изображения не должны перемешиваться, и они должны оставаться в той же ячейке, что и до прокрутки.

Ответы [ 3 ]

1 голос
/ 10 июля 2019

Есть много случаев, которые вам нужно будет обработать при загрузке изображения и его отображении внутри ячейки UITableView / UICollectionView:

  1. Потоки: изображение должно быть присвоено UIImageView на главнойthread.
  2. После завершения загрузки проверьте, видна ли ячейка, и присваиваете ей правильный индекс.

Я настоятельно рекомендую использовать одну из библиотек для этого, например SDWebImage

0 голосов
/ 11 июля 2019

Вы должны создать класс CustomCollectionCell для разделения вашего кода, попробуйте использовать следующий способ, а также для загрузки изображения вы можете использовать SDWebImage

extension ViewController: UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return imagesArray.count
    }

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

        cell.imgView.image = nil
        cell.createImages(imageStringArray: imagesArray[indexPath.row])
        cell.configureTimer()
        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let size = self.collectionView.bounds.size.width / 2 - 5
        return CGSize(width: size, height: (size * 1.5) - 5)
    }



}

class CollectionViewCell: UICollectionViewCell {

    override func awakeFromNib()
    {
        super.awakeFromNib()
        // Initialization code

    }
    var imageArray:[UIImage] = []
    var timer = Timer()
    var photoCount: Int = 0
    @IBOutlet weak var imgView: UIImageView!
    func createImages(imageStringArray:[String])
    {
        self.imageArray.removeAll()
        for imgStr in imageStringArray
        {
          self.imageArray.append(UIImage.init(named: imgStr) ?? UIImage.init())
        }

    }
    func configureTimer()
    {
        self.timer.invalidate()
        self.imgView.image = self.imageArray[self.photoCount] //Set Default Image First Time
        self.timer = Timer.scheduledTimer(withTimeInterval: 2.0, repeats: true, block: { (timer) in
            if (self.photoCount < self.imageArray.count - 1){
                self.photoCount = self.photoCount + 1;
            }else{
                self.photoCount = 0;
            }
            if let imageView = self.imgView {
                UIView.transition(with: imageView, duration: 2.0, options: .transitionCrossDissolve, animations: {
                    imageView.image = self.imageArray[self.photoCount]
                }, completion: nil)
            }
        })
    }
}
0 голосов
/ 10 июля 2019

То, что на самом деле происходит здесь, это то, что collectionView повторно использует предыдущую ячейку, поэтому изображение из предыдущей ячейки загружается в новую ячейку, когда изображение загружается, чтобы удалить это поведение, вам нужно установить заполнитель изображения или , который вы можете установитьизображение пусто

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath)
        let image = cell.viewWithTag(1) as! UIImageView
         image.image = "placeholderImage" // replace it with your place holder image 
//Or 
//     image.image = UIImage()
        let imgArr =  imagesArray[indexPath.row]
        image.downloadImageAndAnimateIt(imageStringArray: imgArr)
        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let size = self.collectionView.bounds.size.width / 2 - 5
        return CGSize(width: size, height: size - 5)
    }

    func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {


    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...