【问题标题】:UITableViewCell duplication after UILabel text editUILabel 文本编辑后的 ​​UITableViewCell 重复
【发布时间】:2018-09-15 01:56:33
【问题描述】:

我有一个UITabelViewCell 用于显示与联系人的活跃聊天。

有一个标签显示每个联系人的未读消息数量,信息来自 Firebase。

打开聊天时,显示未读消息数量的UILabel 应该会消失。但是,一旦这样做,它只会创建另一个单元格,就像这张图片中一样:

然后我点击聊天,聊天打开,然后点击“返回”导航项,显示如下:

这是我的课:

import UIKit
import Firebase

class MessagesViewController: UIViewController, UITableViewDataSource, UITableViewDelegate
{

    private var chats = [PrivateChatLiteObject]()

    @IBOutlet weak var ChatsTableView: UITableView!
    override func viewDidLoad()
    {
        super.viewDidLoad()

        ChatsTableView.dataSource = self
        ChatsTableView.delegate = self
        self.view.layer.backgroundColor = UIColor.white.cgColor
        populateActiveChats()
    }

    private func populateActiveChats()
    {
        let loggedOnUserID = Auth.auth().currentUser?.uid
        let ref = Constants.refs.databaseChatsLite.child(loggedOnUserID!)

            // Retrieve the products and listen for changes
        ref.observe(.value, with:
                { (snapshot) in

                    for child in snapshot.children.allObjects as! [DataSnapshot]
                    {
                        // Code to execute when new product is added

                        let chatValueDictionary = child.value as? NSDictionary
                        self.AddChatToCollections(chatAsDictionary: chatValueDictionary, contactID: child.key)
                        self.DispatchQueueFunc()

                    }
            })
    }

    func AddChatToCollections(chatAsDictionary: NSDictionary!, contactID: String)
    {
        let contactName = chatAsDictionary["userName"] as! String
        //let contactImg = chatAsDictionary["userImageStr"] as? String
        //let lastMsg = chatAsDictionary["lastMessage"] as! String
        let newMsgs = chatAsDictionary["newMessage"] as! Int


        let chatToAdd = PrivateChatLiteObject(chattingWith: contactName, ContactID: contactID, unreadMessages: newMsgs, LastMSG: "")

        chats.append(chatToAdd)
    }

    func DispatchQueueFunc()
    {
        DispatchQueue.main.async
            {
                self.ChatsTableView.reloadData()
        }
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        return chats.count
    }

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

        //cell.ContactImageView = UIImageView.loadImageUsingUrlString(contactImg)
        let index = indexPath.row
        cell.ContactName.text = chats[index].GetContactName()

        cell.ContactID = chats[index].GetContactID()

        let unreadMSGs = chats[index].GetUnreadMessagesNumber()

        if unreadMSGs == 0
        {
            cell.NewNotificationsNum.isHidden = true
        }
        else
        {
            cell.NewNotificationsNum.isHidden = false
            let stringNotifications = String(unreadMSGs)
            cell.NewNotificationsNum.text = stringNotifications
        }

        return cell

    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
    {

        chatIndexToLoad = indexPath.row
        performSegue(withIdentifier: "segue_to_chatroom", sender: self)
    }

    var chatIndexToLoad: Int = -1

    override func prepare(for segue: UIStoryboardSegue, sender: Any?)
    {
        if (segue.identifier == "segue_to_chatroom")
        {
            let destination = segue.destination as! PrivateChatViewController
            destination.senderId = Constants.refs.currentUserInformation!.uid
            //destination.senderDisplayName = Constants.refs.currentUserInformation?.displayName
            destination.contactDisplayName = chats[chatIndexToLoad].GetContactName()
            destination.contactID = chats[chatIndexToLoad].GetContactID()

        }
    }

}

我想它必须做一些事情,当节点内部发生变化时从 Firebase 读取数据并重新添加相同的节点。只有在添加新节点时,我才需要一种方法来实际启动 Firebase 的读取。我尝试使用.childAdded,但没有奏效。有谁知道如何解决这个问题?

我唯一能想到的就是每当将项目添加到收藏夹时,检查是否尚不存在具有相同联系人 ID 的聊天,但这对性能不利。

【问题讨论】:

  • 似乎不是重用问题。我认为这是因为你总是附加内容而不是替换已经存在于self.ContactNames 中的值。
  • 旁注:请不要以大写字母开头的 var 和方法命名为 Classes 名称。此外,您应该使用 ONE 数组,因为 ContactNames NewMsgsContactIDs 是链接的。
  • 我想创建一个“聊天”数组,但为此我必须创建一个聊天实例,并且聊天实例内部有属性,我不想在这里实例化。关于如何改进这一点的任何建议?
  • "我不想在这里实例化" 为什么?只是为什么?您可以创建自己的具有这 3 个属性的自定义对象,或者严重使用 Dict 来保存它们。
  • 聊天实例保存所有相关消息。我不希望将它们加载到此屏幕中,因为它不是完成它的地方,但只有在加载聊天之后

标签: ios swift uitableview firebase uilabel


【解决方案1】:

当您在 FirebaseDatabase 中查询某些数据而不是使用

ref.observe(.value, with: { (snapshot) in

             //your implementation
    })

尝试使用

ref.observeSingleEvent(of: .value, with: { (snapshot) in

             //your implementation
})

当我在我的一个项目中使用 FirebaseDatabase 时,我注意到了这种奇怪的行为。 ref.observe 被多次调用并导致了意想不到的结果,而 ref.observeSingleEvent 做得很好。

【讨论】:

    【解决方案2】:

    我不完全知道您的要求,但如果您愿意,我可以在下面分享我当前的代码。此外,确保将您的 UITableView 作为委托和数据源附加到您的 ViewController,并将其添加到您的视图控制器类:

    class NearbyViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
        @IBOutlet weak var nearbyTableView: UITableView!
    var myList: [String] = []
    var handle:DatabaseHandle?
    var ref:DatabaseReference?
    
    
    
    
    
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return myList.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
        let cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
        var (cellName) = myList[indexPath.row]
        cell.textLabel?.text = cellName
    
        return cell
    
    }
    
     func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
        var (cellName) = myList[indexPath.row]
    
        print("row\(indexPath.row)")
        print("name: \(cellName)")
    
    
    }
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
    
    
    
    
    
        ref = Database.database().reference()
        handle = ref?.child("list").observe(.childAdded, with: { (snapshot) in
            if let item = snapshot.value as? String
            {
                self.myList.append(item)
                self.nearbyTableView.reloadData()
            }
        })
    }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-25
      • 1970-01-01
      • 1970-01-01
      • 2017-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多