CollectionViewCell отображает неправильное изображение при быстрой прокрутке - PullRequest
0 голосов
/ 05 октября 2018

Я знаю, что люди задавали этот вопрос раньше, но способ, которым я реализовал свой код, кажется немного другим, потому что я использую теги ячеек.Я действительно доволен тем, как все загружается ДРУГОЙ, тогда, когда я слишком быстро прокручиваю изображения, они дрожат и оказываются не на своем месте.Как я могу решить эту проблему?

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

        if let activity = cell.viewWithTag(103) as? UIActivityIndicatorView {
            activityMain.isHidden = true
            activityMain.stopAnimating()
            activity.isHidden = false
            activity.startAnimating()

        }

        DispatchQueue.main.async {
        if let pageLabel = cell.viewWithTag(101) as? UILabel {
            pageLabel.text = self.Networking.fetchedPagesNumbers.reversed()[indexPath.row]
            }
        }

        if let image = cell.viewWithTag(100) as? UIImageView {

            image.image = UIImage(named: "Rectangle")

            DispatchQueue.global(qos: .background).async {
                do{
                    let data = try Data.init(contentsOf: URL.init(string:self.Networking.fetchedPagesURLs.reversed()[indexPath.row])!)

                    DispatchQueue.main.async {

                        let imageToCache = UIImage(data: data)!

                        imageCache.setObject(imageToCache, forKey: self.Networking.fetchedPagesURLs.reversed()[indexPath.row] as NSString )

                        image.image = imageToCache

                            if let activity = cell.viewWithTag(103) as? UIActivityIndicatorView {
                                activity.isHidden = true
                                activity.stopAnimating()
                                collectionView.isScrollEnabled = true
                            }
                    }
                }
                catch {
                    // error
                }
            }
        }
        return cell
    }

Ответы [ 3 ]

0 голосов
/ 05 октября 2018

В классе collectionViewCell вы должны переопределить prepareForReuse ()

override func prepareForReuse() {
    super.prepareForReuse()

    self.pageLabel.text = nil
    self.imageView.image = UIImage()
}
0 голосов
/ 05 октября 2018

Когда дело доходит до кэширования изображений, я бы порекомендовал Зимородок : https://github.com/onevcat/Kingfisher

Он очень прост в использовании:

let url = URL(string: "url_of_your_image")
imageView.kf.setImage(with: url)
0 голосов
/ 05 октября 2018

1 - вместо тегов

if let activity = cell.viewWithTag(103) as? UIActivityIndicatorView {

создать IBOutlet для каждого элемента пользовательского интерфейса внутри пользовательского класса ячейки с приведением ячейки

let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PageCell", for: indexPath) 
 as! PageCell

2 - не нужно DispatchQueue.main.async в

DispatchQueue.main.async {
 if let pageLabel = cell.viewWithTag(101) as? UILabel {

, поскольку код cellForRowAt по умолчанию выполняется в основной очереди

3 - вместо тяжелой работы с загрузкой образа .cache используйте SDWebImage

image.sd_setImage(with: URL(string:self.Networking.fetchedPagesURLs.reversed()[indexPath.row])!), placeholderImage: UIImage(named: "placeholder.png"))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...