2017-11-29 18 views
0

enter image description hereUItableView重複するセルを表示しています。データには何が間違っていますか?

この時点で何をすべきかわかりません。私は絶え間なく試してみたいと思っています。

私はチュートリアル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が同じデータをロードしていました。全員のおかげで助けてくれる

+0

"message.toId == m.fromId && m.fromId == message.toId" Both &&の両側はちょうど異なる順序で同じであるように見えます...それはタイプミスですか?私はまた、括弧を使用して評価する方法を明確にすることをお勧めします(私はかなり確信しています&&は||を優先しますが、安全のためです)。 – ghostatron

答えて

0

セルは再利用され、前のUI情報が保持されます。あなたのCellForRowAt方法では、アレイをチェックするfirebase 試してからスナップショットを取得するときは、必ず配列に同じ値を追加しているので、それが引き起こされることが明示的に画像等、人物名、タイムスタンプ、

+3

あなたがdownvoteしようとしている場合は、有効かつ有用な答えを感じたことは、理由についてのフィードバックを提供してください。実際には、新規ユーザーは、セルが再利用されたときにUIオブジェクトに以前と同じ情報が表示されることに気付かないことがよくあります。 – ghostatron

+0

これも私の最初の考えでした。セル内のデータの唯一のカスタマイズは 'cell.message = message; 'という代入にあり、そのコードは表示されません。問題は 'UITableView'になく、' UserCell'かデータソースにあります。 –

0

を設定する必要があります重複する
セル内の同じイメージが画像をnilに設定しないようにしてから、常に画像を表示したり、画像のプレースホルダーを指定したりする。

関連する問題