Firebase聊天用户正在输入指示器单元格

时间:2018-10-30 19:46:54

标签: swift firebase firebase-realtime-database uicollectionview uicollectionviewcell

我有一个Firebase实时数据库,允许用户相互发送直接消息,如下所示:

chats
-- fromUserID
---- toUserID
---- newMessages: Bool
---- isTyping: Bool
---- messageID_1
------ messageTimeStamp
---- messageID_2
------ messageTimeStamp
---- messageID_3
------ messageTimeStamp

messages
-- messageID
---- messageFromID
---- messageToID
---- messageText
---- messageTimeStamp
---- messageRead

如您所见,我在每次聊天的聊天记录中都有一个密钥,该密钥是一个布尔值,用于指示用户是否在键入。我将其在textFieldDidChange中更改为true(如果textView.text!= nil,如果isSending = false,则只是为了限制请求)。我将计时器设置为10秒,以在用户关闭应用程序或其他情况时自动将“ isTyping”值恢复为false。

func textViewDidChange(_ textView: UITextView) {

    if(!isSending && textView.text != nil) {

        isSending = true

        if let messagePartner = messagePartner {

            Ref.child("chats").child(messagePartner).child(loggedInUserID).updateChildValues(["isTyping": true])

        }

    }

    if(isSending && textView.text == nil) {

        if let messagePartner = messagePartner {

            Ref.child("chats").child(messagePartner).child(loggedInUserID).updateChildValues(["isTyping": false])

        }
    }

}

func observeTyping() {

    if let messagePartner = messagePartner {

        typingObserver = Ref.child("chats").child(loggedInUserID).child(messagePartner).observe(.childChanged) { (snapTyping) in

            if(snapTyping.key == "isTyping") {

                let isTypingValue = snapTyping.value as? Bool

                if(isTypingValue == true) {

                    self.isTyping = true

                    if let messagePartnerFirstName = self.messagePartnerFirstName, let messagePartnerLastName = self.messagePartnerLastName {

                        self.navigationItem.title = messagePartnerFirstName + " " + messagePartnerLastName + " is typing..."

                    }

                } else {

                    self.isTyping = false
                    self.typingTimer?.invalidate()

                    if let messagePartnerFirstName = self.messagePartnerFirstName, let messagePartnerLastName = self.messagePartnerLastName {

                        self.navigationItem.title = messagePartnerFirstName + " " + messagePartnerLastName

                    }

                }

            }

        }

    }

}

当前,当isTyping为true时,我将navigationItem.title更改为“ username正在键入...”,而当isTyping为false时,仅更改为“ username”。就像魅力一样。

这很简单,也很容易理解。但是,我想更改行为以显示正在键入的用户单元格,其中仅带有“ ...”,有点类似于iOS Messenger和Facebook Messenger。但是,关于如何实现这一点,我还有两个问题。

首先:我正在从messages.count返回我的collectionView中的单元格数量。用户输入时,是否应该在message.count后面附加一条消息?

第二,我想在用户停止键入或定时器触发后(10秒后)删除此单元格。我应该如何在正确的indexPath上执行此操作?我可以保存显示该单元格的indexPath,然后再将其删除吗?

第三个也是最后一个:我希望此单元格始终位于聊天的底部。因此,当其他用户输入消息时,...指示器仍应位于底部。我还能做到吗?

任何向我指出正确方向的想法或技巧将不胜感激!谢谢你们。

编辑:考虑到我的帖子,我现在正在考虑另一种方式:基于聊天室但在其中仅包含...的情况下,引入另一个自定义UICollectionViewCell是个好主意吗?并基于isTyping更改numberOfItemsInSection?像这样:

if(isTyping) {
    return messages.count + 1
} else {
    return messages.count
}

我只是大声思考-请让我知道你们的想法或是否有更好的解决方案。

1 个答案:

答案 0 :(得分:0)

最终使用补充视图(Footer)对其进行了修复,我根据Bool isTyping更改了高度(如果未键入,则将框架设置为width&height 0),并相应地更改了contentInset。然后,当Fitebase观察器中的isTyping发生更改时,我reloadData()来显示或隐藏页脚,效果很好!