目前还不确定该怎么办.....我已经被困了好几天。
我使用的是教程here。
我使用了他的代码结构,因为我是初学者,这似乎是最佳实践。重复的单元格也有不准确的时间发送和第一条消息。我真的需要帮助。
这是消息控制器(您在上面看到的屏幕):
import UIKit
import Firebase
class MessagesViewController: UIViewController , UITableViewDelegate , UITableViewDataSource {
@IBOutlet weak var messagesLabelOutlet: UILabel!
@IBOutlet weak var messagesTableView: UITableView!
var newUser : User?
var messageArr = [Message]()
var messageDict = [String: Message]()
override func viewDidLoad() {
super.viewDidLoad()
messagesTableView.dataSource = self
messagesTableView.delegate = self;
self.messagesTableView.register(UserCell.self, forCellReuseIdentifier: "cellId")
checkIfUserIsLoggedIn()
messageArr.removeAll()
messageDict.removeAll()
messagesTableView.reloadData()
observeUserMessages()
configureTableView()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return messageArr.count;
}
func configureTableView()
{
messagesTableView.rowHeight = UITableViewAutomaticDimension;
messagesTableView.estimatedRowHeight = 120.0;
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 72;
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.newUser = User()
if let chatPartnerId = messageArr[indexPath.row].chatPartnerId(){
self.newUser?.toId! = chatPartnerId;
let chatPartnerDataRef = Database.database().reference().child("users").child(chatPartnerId)
chatPartnerDataRef.observeSingleEvent(of: .value) { (snapshot) in
guard let dict = snapshot.value as? [String : AnyObject] else{
return
}
self.newUser?.userName = dict["username"] as? String
self.newUser?.picURL = dict["pic"] as? String
self.newUser?.score = dict["score"] as? String
self.performSegue(withIdentifier: "goToChatLogControllerPlzFromMessages", sender: self)
}
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath) as! UserCell
let message = messageArr[indexPath.row]
cell.textLabel?.font = UIFont(name: "Avenir Book" , size: 19);
cell.detailTextLabel?.font = UIFont(name: "Avenir Light" , size: 14);
cell.message = message;
return cell;
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// do not remove
if segue.identifier == "goToChatLogControllerPlzFromMessages"{
print("going to chat log")
let recieveVC = segue.destination as! ChatLogController
if let textUser = newUser{
recieveVC.user = textUser;
}
}
}
func checkIfUserIsLoggedIn()
{
if Auth.auth().currentUser?.uid == nil{
print("uid is nil")
performSegue(withIdentifier: "noUserFoundGoingBackToLogin", sender: self);
}
else{
let uid = Auth.auth().currentUser?.uid
Database.database().reference().child("users").child(uid!).observeSingleEvent(of: .value, with: { (snapshot) in
})
}
}
func observeUserMessages(){
guard let uid = Auth.auth().currentUser?.uid else{
checkIfUserIsLoggedIn()
return;
}
let ref = Database.database().reference().child("user-messages").child(uid)
ref.observe(.childAdded) { (snapshot) in
let messageId = snapshot.key
let messagesRef = Database.database().reference().child("messages").child(messageId)
messagesRef.observeSingleEvent(of: .value, with: { (snapshot) in
// no duplicate texts as of here
if let dict = snapshot.value as? [String : AnyObject]
{
let message = Message()
message.fromId = dict["fromid"] as? String;
message.text = dict["text"] as? String;
message.timestamp = dict["timestamp"] as? String;
message.toId = dict["toid"] as? String;
self.messageArr.append(message)
if let toID = message.toId{
for m in self.messageArr{
if message.toId == m.toId && m.fromId == message.fromId || message.toId == m.fromId && m.fromId == message.toId{
self.messageDict[toID] = message;
}
}
self.messageArr = Array(self.messageDict.values)
self.messageArr.sort(by: { (message1, message2) -> Bool in
let time1 = Int(truncating: (message1.timestamp?.numberValue)!)
let time2 = Int(truncating: (message2.timestamp?.numberValue)!)
return time1 > time2
})
}
DispatchQueue.main.async {
print(message.text!)
self.messagesTableView.reloadData()
}
}
})
}
}
}
我已将错误缩小到此方法:
func observeUserMessages(){
guard let uid = Auth.auth().currentUser?.uid else{
checkIfUserIsLoggedIn()
return;
}
let ref = Database.database().reference().child("user-messages").child(uid)
ref.observe(.childAdded) { (snapshot) in
let messageId = snapshot.key
let messagesRef = Database.database().reference().child("messages").child(messageId)
messagesRef.observeSingleEvent(of: .value, with: { (snapshot) in
// no duplicate texts as of here
if let dict = snapshot.value as? [String : AnyObject]
{
let message = Message()
message.fromId = dict["fromid"] as? String;
message.text = dict["text"] as? String;
message.timestamp = dict["timestamp"] as? String;
message.toId = dict["toid"] as? String;
self.messageArr.append(message)
if let toID = message.toId{
for m in self.messageArr{
if message.toId == m.toId && m.fromId == message.fromId || message.toId == m.fromId && m.fromId == message.toId{
self.messageDict[toID] = message;
}
}
self.messageArr = Array(self.messageDict.values)
self.messageArr.sort(by: { (message1, message2) -> Bool in
let time1 = Int(truncating: (message1.timestamp?.numberValue)!)
let time2 = Int(truncating: (message2.timestamp?.numberValue)!)
return time1 > time2
})
}
DispatchQueue.main.async {
print(message.text!)
self.messagesTableView.reloadData()
}
}
})
}
}
我发现使用这个for循环,我要么加载所有用户,要么重复。
for m in self.messageArr{
if message.toId == m.toId && m.fromId ==
message.fromId || message.toId == m.fromId && m.fromId == message.toId{
self.messageDict[toID] = message;
}
}
感谢所有想要帮助的人。
更新
我在4天后解决了这个问题。解决方案是在数据中,我正在加载具有toID和fromID相同的数据。谢谢大家的帮助
答案 0 :(得分:0)
单元格被重用,这意味着它们保留了以前的UI信息。在您的CellForRowAt方法中,您需要显式设置图像,人名,时间戳等。
答案 1 :(得分:0)
可能是因为从firebase获取快照时始终向数组附加相同的值 尝试检查数组是否有重复项 为了防止单元格中的相同图像,只需将图像设置为nil,然后提供所需的图像或提供图像占位符,因为单元格总是被重用