Swift tableView 单元格在滚动时消失

Swift tableView Cells disappears on scroll

尝试使用 tableView 在我的应用程序中添加聊天功能,但每当我滚动聊天时,一些单元格就会消失,我不确定为什么。感谢任何帮助。

tableView 连接到故事板中的数据源和委托。

我已经在 xib 文件中创建了单元格本身,并且根据它是发件人消息还是接收到的消息,单元格将显示不同。 这是每个单元格的代码:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "customMessageCell", for: indexPath) as! CustomMessageCell

    //Sets cell to message

    senderId = messageArray[indexPath.row].fromId

    if senderId == Auth.auth().currentUser?.uid as String? {
        //Messages We Sent 
        cell.ourMessageBody.text = messageArray[indexPath.row].messageBody

        cell.ourMessageBackground.backgroundColor = UIColor(displayP3Red: 59/255.0, green: 89/255.0, blue: 152/255.0, alpha: 1)
        cell.ourMessageBody.textColor = UIColor.white

        cell.avatarImageView.isHidden = true
        cell.messageBackground.isHidden = true

    } else{
        //Messages someone else sent
        cell.messageBody.text = messageArray[indexPath.row].messageBody
        cell.avatarImageView.backgroundColor = UIColor(white: 0.95, alpha: 1)
        cell.messageBackground.backgroundColor = UIColor(white: 0.95, alpha: 1)
        cell.ourMessageBackground.isHidden = true
        //toId ProfileImage
        if let imageID = toId{
            print(imageID)
            let imagesStorageRef = Storage.storage().reference().child("profilepic/").child(imageID)
            imagesStorageRef.getData(maxSize: 1*1024*1024, completion: { (data, error) in
                if error != nil{
                    print(error)
                    return
                }
                DispatchQueue.main.async {
                    cell.avatarImageView?.image = UIImage(data: data!)
                }

            })

        }
    }

    return cell
}

这里是检索消息的方法:

    func retrieveMessages() {

    let testUserOrAd = SwipingView.myAdvertiserVar.advertiser
    print("testing result: \(testUserOrAd) your are a User")

    //if advertiser
    if testUserOrAd == true{
        if let testId = self.toId{
            let MessageDB = Database.database().reference().child("Users").child(toId!).child("Messages").child(uid!)

            MessageDB.observe(.childAdded) { (snapshot) in
                let snapshotValue =  snapshot.value as! Dictionary<String,String>

                let text = snapshotValue["MessageBody"]!
                let fromId = snapshotValue["FromId"]

                let message = Message()
                message.messageBody = text
                message.fromId = fromId

                self.messageArray.append(message)

                self.configureTableView()
                self.messageTableView.reloadData()
            }
        }

    }else{
        //if user

        let MessageDB = Database.database().reference().child("Users").child(uid!).child("Messages").child(toId!)

        MessageDB.observe(.childAdded) { (snapshot) in
            let snapshotValue =  snapshot.value as? [String: AnyObject]

            let text = snapshotValue!["MessageBody"] as? String
            let fromId = snapshotValue!["FromId"] as? String

            let message = Message()
            message.messageBody = text
            message.fromId = fromId

            self.messageArray.append(message)

            self.configureTableView()
            self.messageTableView.reloadData()
        }

    }
}

这是结果:

你的代码是错误的,因为你配置了你的单元格一次(在 tableView:cellForRowAt: 方法中)但是当你滚动 table 视图时,如果用户交替,avatarImageViewmessageBackgroundourMessageBackground 最终将全部隐藏。

尝试像这样更新您的代码:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  let cell = tableView.dequeueReusableCell(withIdentifier: "customMessageCell", for: indexPath)

  cell.ourMessageBackground.backgroundColor = UIColor(displayP3Red: 59/255.0, green: 89/255.0, blue: 152/255.0, alpha: 1)
  cell.ourMessageBody.textColor = UIColor.white
  cell.avatarImageView.backgroundColor = UIColor(white: 0.95, alpha: 1)
  cell.messageBackground.backgroundColor = UIColor(white: 0.95, alpha: 1)

  self.tableView(tableView, willDisplay: cell, forRowAt: indexPath)

  return cell
}

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
  guard let cell = cell as? CustomMessageCell else { return }

  //Sets cell to message

  let senderId = messageArray[indexPath.row].fromId

  if senderId == Auth.auth().currentUser?.uid as String? {
    //Messages We Sent
    cell.ourMessageBody.text = messageArray[indexPath.row].messageBody

    cell.avatarImageView.isHidden = true
    cell.messageBackground.isHidden = true
    cell.ourMessageBackground.isHidden = false
  } else {
    //Messages someone else sent
    cell.messageBody.text = messageArray[indexPath.row].messageBody

    cell.avatarImageView.isHidden = false
    cell.messageBackground.isHidden = false
    cell.ourMessageBackground.isHidden = true

    //toId ProfileImage
    if let imageID = toId {
      let imagesStorageRef = Storage.storage().reference().child("profilepic/").child(imageID)
      imagesStorageRef.getData(maxSize: 1*1024*1024, completion: { (data, error) in
        if error != nil{
          print(error)
          return
        }

        DispatchQueue.main.async {
          guard let c = tableView.cellForRow(at: indexPath) else { return }

          c.avatarImageView?.image = UIImage(data: data!)
        }

      })

    }
  }
}

此外,由于头像获取是在后台进行的,因此获取数据时单元格可能已更改。所以你必须确保单元格仍然显示。并且你应该缓存头像以避免每次都获取它。