Неправильные изображения, иногда назначаемые UIImageView в UITableViewCell - PullRequest
0 голосов
/ 12 декабря 2018

У меня есть групповой чат с несколькими сотнями человек, и когда я выполняю быструю прокрутку, иногда либо пользовательские изображения переходят от чего-то к чему-то другому, либо для пользователя отображаются неправильные изображения.

Я подписался на несколько других сообщений SO, но все еще, кажется, что-то делаю неправильно.Что-нибудь выделяется здесь и что я могу сделать, чтобы решить эту проблему?

Спасибо!

final class MessageCell: UITableViewCell {

    private lazy var profileImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.layer.cornerRadius = 20
        imageView.clipsToBounds = true

        return imageView
    }()

    // MARK: – Init

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        selectionStyle = .none

        addSubview(profileImageView)

        setupConstraints()
    }

    private func setupConstraints() {
        constrain(profileImageView) {
            let size: CGFloat = 36
            $0.width == size
            $0.height == size
            $0.bottom == $0.superview!.bottom - CGFloat(3)
            $0.left == $0.superview!.left + CGFloat(12)
        }
    }


    func configure(with presentable: CellPresentable) {
        self.presentable = presentable

        if let sender = presentable.sender, presentable.isFirstMessage {
            profileImageView.setImage(url: (sender.object(forKey: "picture") as? PFFile)?.url, fallbackText: presentable.username)
        } else {
            PFUser.query()?.whereKey("objectId", equalTo: presentable.message.senderUserId).getFirstObjectInBackground { [weak self] user, error in
                self?.profileImageView.setImage(url: (user?.object(forKey: "picture") as? PFFile)?.url, fallbackText: presentable.username)
            }
        }
    }

    // MARK: Reuse -

    override func prepareForReuse() {
        super.prepareForReuse()

        profileImageView.kf.cancelDownloadTask()
        profileImageView.image = nil
    }

}

В моем контроллере вида:

let cell = tableView.dequeueReusableCell(withIdentifier: "MessageCell") as! MessageCell
let presentable = CellPresentable(for: message, isFirstMessage: isFirstMessage, isLastMessage: isLastMessage)
cell.configure(with: presentable)

return cell

Ответы [ 3 ]

0 голосов
/ 12 декабря 2018

Попробуйте следующий код в функции конфигурации в MessageCell

profileImageView.image = nil

Итак, новый код функции:

func configure(with presentable: CellPresentable) {
    self.presentable = presentable
    profileImageView.image = nil
    if let sender = presentable.sender, presentable.isFirstMessage {
        profileImageView.setImage(url: (sender.object(forKey: "picture") as? PFFile)?.url, fallbackText: presentable.username)
    } else {
        PFUser.query()?.whereKey("objectId", equalTo: presentable.message.senderUserId).getFirstObjectInBackground { [weak self] user, error in
            self?.profileImageView.setImage(url: (user?.object(forKey: "picture") as? PFFile)?.url, fallbackText: presentable.username)
        }
    }
}
0 голосов
/ 12 декабря 2018

Эти ответы полезны, но то, что действительно двигало иглой, было то, что я после того, как я сделал PFUser.query(), я не хранил этого извлеченного пользователя везде, поэтому, если я выбрал пользователя 5 один раз, я выбирал их каждый раз, когда появлялись их изображения,Вот что стало причиной задержки.Вместо этого я просто удалил этот вызов и использовал альтернативу для этих пользователей (поскольку эти пользователи больше не входят в мою группу), и прокрутка значительно улучшилась.

0 голосов
/ 12 декабря 2018

Вы имеете дело с состоянием гонки, которое связано с асинхронностью функции getFirstObjectInBackground из PFUser.query () и тем, что ваши ячейки удаляются из системы и повторно используются системой до возвращения закрытия этой функции.

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

Когда вы вызываете getFirstObjectInBackground (), его закрытие захватывает self .Ваша проблема в том, что self на данный момент используется повторно.Он расположен по другому пути индекса и настроен с другими данными, поэтому изображение, только что возвращенное вам асинхронно, больше не является свежим или уместным.

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

 guard presentable == self?.presentable else {return}
 self?.profileImageView.setImage(url: (user?.object(forKey: "picture") as? PFFile)?.url, fallbackText: presentable.username)  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...