Ячейка не показывает изображение после загрузки из Firebase Swift - PullRequest
0 голосов
/ 25 мая 2018

У меня есть UITableViewCell, который показывает изображение или текст.Я установил для UIImageView высоту и ширину <= 150, чтобы это не влияло на высоту ячейки, если изображение отсутствует, но текст есть.(это приложение для обмена сообщениями) </p>

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

Перед загрузкой изображения:

enter image description here

После изображенияуспешно загружен:

enter image description here

как вы можете видеть, он не показывает, только представление было расширено

Если пользователь нажимает кнопку НАЗАД и снова появляется в этом виде,

enter image description here

изображение теперь отображается.

как мне решить эту проблему?потому что я не могу написать tableview.reloaddata() в tableviewcell.

для моего кода в tableviewcell для настройки моей ячейки:

func configCell(message: Message) {

    self.message = message

    if message.fromId == currentUser {

        sentView.isHidden = false

        sentMsgLabel.text = message.textMessages

        receivedMsgLabel.text = ""

        receivedView.isHidden = true

        timeReceived.text = ""

        timeSent.text = message.timestamp

        youLabel.text = "You"

        themLabel.text = ""


        if let ImageUrl = message.imageUrlLink {

            self.receivedimg.loadImageUsingCacheWithUrlString(ImageUrl)
        }
        }

        else {

        sentView.isHidden = true

        sentMsgLabel.text = ""

        receivedMsgLabel.text = message.textMessages

        receivedMsgLabel.isHidden = false

        timeReceived.text = message.timestamp

        timeSent.text = ""

        // setting name for receipient
        Database.database().reference().child("users").child(message.fromId!).child("name").observe(.value) { (datasnapshot) in
        if let name = datasnapshot.value as? String {
                self.themLabel.text = name
            }
        }

        youLabel.text = ""
    }
}

для моего loadImageUsingCacheWithUrlString кода будет расширением, как показано ниже:

let imageCache = NSCache<AnyObject, AnyObject>()

    extension UIImageView {

    func loadImageUsingCacheWithUrlString(_ urlString: String) {

        self.image = nil

        //check cache for image first
        if let cachedImage = imageCache.object(forKey: urlString as AnyObject) as? UIImage {
            self.image = cachedImage
            return
        }

        //otherwise fire off a new download
        let url = URL(string: urlString)
        URLSession.shared.dataTask(with: url!, completionHandler: { (data, response, error) in

            //download hit an error so lets return out
            if error != nil {
                print(error ?? "")
                return
            }

            DispatchQueue.main.async(execute: {

                if let downloadedImage = UIImage(data: data!) {
                    imageCache.setObject(downloadedImage, forKey: urlString as AnyObject)

                    self.image = downloadedImage
                }
            })

        }).resume()
    }

}

Ответы [ 4 ]

0 голосов
/ 25 мая 2018

Похоже, что этот код выполняется один раз, но ваш UITableView все равно загружает ячейку, поскольку счетчик равен 2. Когда вы передаете свой объект Message в класс UICollectionViewCell внутри вашего cellForRowAt indexPath метода, вы захотите использовать didSet в этом сообщении, а затем вызвать вашу функцию.Это означает, что каждый раз, когда передается сообщение и когда оно передается, все, что находится внутри didSet, будет выполняться.

Внутри вашего класса UICollectionViewCell:

var message: Message? {
    didSet {
        configCell(message)
    }
}

Класс с вашим UITableViewController:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = // your cell here dequeue cell and downcast as your cell class e.g as! MyCell

    cell.message = yourMessagesArray[indexPath.row]

    return cell
}
0 голосов
/ 25 мая 2018

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

Вместо того, чтобы загружать и ловить себя, я рекомендую использовать среду KingFisher, она делает почти все, что нам нужно при работе с изображением с удаленного сервера: загрузка, ловля, предварительная выборка... и покажите свое изображение сразу после загрузки

0 голосов
/ 25 мая 2018

В конце концов я пробовал так много способов. В моем ViewDidload я просто добавил задержку

 DispatchQueue.main.asyncAfter(deadline: .now() + 1){
        self.tableView.reloadData()
    }

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

0 голосов
/ 25 мая 2018

Вместо выполнения действия в UITableViewCell do действия внутри cellForRowAt

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    //Your actuions here
}

Тогда вы можете использовать tableView.reloadData() внутри вашего UITableViewController

Надеюсь, это поможетрешить вашу проблему.

...