【问题标题】:How to properly display pictures in a TableView from Firebase Storage in SWIFT如何在 SWIFT 中的 Firebase 存储中正确显示 TableView 中的图片
【发布时间】:2020-12-23 19:26:42
【问题描述】:

我有一个聊天应用程序,人们可以在其中进行群组交谈,并且每个单元格中都会显示一张小图片以显示谁在说话。我设法从 Firebase 存储中显示这些图片,但 显示在正确位置的图片并不总是正确。

只有当我转到上一个 View Controller 并返回聊天 View 以查看每个单元格中正确显示的图片时,它才有效。

我尝试使用 DispatchQueue.main.async {} 可能不是很好,因为它对我不起作用。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
 
    let message = messageArray[indexPath.row]
    let cell = tableView.dequeueReusableCell(withIdentifier: "customMessageCell", for: indexPath) as! CustomMessageCell
    cell.selectionStyle = .none
// CHANGE TEXT ACCORDING TO SENDER
    if message.sender == Auth.auth().currentUser?.email{
        cell.messageBubble.backgroundColor = UIColor(red:0.30, green:0.68, blue:1.5, alpha:1.0)
        // ...
    } else {
        cell.messageBubble.backgroundColor = UIColor(red:0.94, green:0.94, blue:0.94, alpha:1.0)
        // ...
    }
   
    let theTimeStamp = messageArray[indexPath.row].createdAt
    let doubleTime = Double(theTimeStamp)
    let myDate = Date(timeIntervalSince1970: doubleTime )
    let dateToShow = myDate.calenderTimeSinceNow()
    
    cell.messageBodyTextView.text = messageArray[indexPath.row].messageBody
    cell.usernameLabel.text = messageArray[indexPath.row].name
    cell.timeLabel.text = dateToShow

     let imagePath = self.storageRef.reference(withPath:"\(message.uid)/resizes/profilImage_150x150.jpg")                   
               imagePath.getData(maxSize: 10 * 1024 * 1024) { (data, error) in
                                                               
        if let error = error {
            cell.userPicture.image = UIImage(named: "emptyProfilPic")
                                                                                                                  
        cell.userPicture.layer.cornerRadius = cell.userPicture.frame.height / 2
        cell.userPicture.clipsToBounds = true
                                                                   
        print("Got an error fetching data : \(error.localizedDescription)")                                                                       

       return
  }
                                                                
  if let data = data {
    cell.userPicture.image = UIImage(data: data)
    cell.userPicture.layer.cornerRadius = cell.userPicture.frame.height / 2
    cell.userPicture.clipsToBounds = true
                      }
    }
 
    return cell
}

感谢您的帮助!

【问题讨论】:

    标签: swift firebase-realtime-database firebase-storage


    【解决方案1】:

    您必须通过适当的覆盖 prepareForReuse() 来准备可重用单元格。

    对于更简洁的代码,我建议您在单独的 cocoa Touch 类中实现单元格,以便更容易覆盖和准备下一个数据传入,避免您的问题。

    我的意思是这样的:

    class mineCell:UITableViewCell {
    @IBOutlet weak var text:UILabel!
    @IBOutlet weak var img:UIImageView!
    
    override func awakeFromNib() {
            super.awakeFromNib()
           
        }
    func updateCell(dataIn){
    .
    .
    }
    override func prepareForReuse() {
    text.text = ""
    img.image = nil
    }
    

    在您的 cellForRowAt 表实现中,只需调用更新函数并像这样传递您的数据:

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let identifier = "mineCell"
            
            
            if let cell = mineTable.dequeueReusableCell(withIdentifier: identifier, for: indexPath) as? mineCell {
                
               
                updateCell(dataIn)
                
                
                
                return cell
            }
            return mineCell()
        }
    

    通过这种方式,您始终可以确保您的单元格为每次重用做好准备,并且不会从上面的单元格中加载错误的数据。

    【讨论】:

    • 感谢您的回复。我已经按照您所说的做了,但是您能否更准确地了解函数 func updateCell(dataIn){} 和 dataIn 的内容?我做错了(我是 swift 新手)
    • 所以我使用 override prepareForReuse() 在重用它之前清理单元格,但它对我不起作用。你有更多的见解吗?
    • @olivierm 通常你遇到的问题是你没有准备好覆盖的单元格。正如我从您的代码中了解到的那样,单元格没有准备好重用,因此,如果在下载正确的内容时出现问题,您会看到缓存的内容。我的代码是向您提示使用 UITableViewCell 的正确方法以及该类中的正确覆盖。您是否在覆盖中放置了 print("something") 以确保正确触发?
    • 是的,我在 override 中放了一个 print() 并确认它按预期打印,这就是我感到困惑的原因
    【解决方案2】:

    只是让您知道,问题是我在每条消息加载后都重新加载表视图。相反,最好的解决方案是在表格视图中添加一行,而不在每条消息后重新加载表格视图:

     self.ConvertationTableView.insertRows(at: [IndexPath(row: self.messageArray.count - 1, section: 0)], with: .automatic)
    

    【讨论】:

      猜你喜欢
      • 2017-01-14
      • 2020-03-03
      • 2022-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-08
      • 1970-01-01
      • 2022-11-02
      相关资源
      最近更新 更多