UItableView重複するセルを表示しています。データには何が間違っていますか?
この時点で何をすべきかわかりません。私は絶え間なく試してみたいと思っています。
私はチュートリアル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 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;
}
}
ご協力いただきありがとうございます。
UPDATE
は、私は4 F *** INGの日後に問題を解決しました。解決策がデータにあった場合、toIDとfromIDが同じデータをロードしていました。全員のおかげで助けてくれる
"message.toId == m.fromId && m.fromId == message.toId" Both &&の両側はちょうど異なる順序で同じであるように見えます...それはタイプミスですか?私はまた、括弧を使用して評価する方法を明確にすることをお勧めします(私はかなり確信しています&&は||を優先しますが、安全のためです)。 – ghostatron