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 视图时,如果用户交替,avatarImageView
,messageBackground
和 ourMessageBackground
最终将全部隐藏。
尝试像这样更新您的代码:
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!)
}
})
}
}
}
此外,由于头像获取是在后台进行的,因此获取数据时单元格可能已更改。所以你必须确保单元格仍然显示。并且你应该缓存头像以避免每次都获取它。
尝试使用 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 视图时,如果用户交替,avatarImageView
,messageBackground
和 ourMessageBackground
最终将全部隐藏。
尝试像这样更新您的代码:
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!)
}
})
}
}
}
此外,由于头像获取是在后台进行的,因此获取数据时单元格可能已更改。所以你必须确保单元格仍然显示。并且你应该缓存头像以避免每次都获取它。