У меня есть база данных 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» в значение «ложь» в случае, если пользователь закрывает приложение или что-то подобное.
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
}
}
}
}
}
}
В настоящее время я изменяю navigationItem.title на «username is typing ...», когда isTyping равен true, или просто «username», когда isTyping равен false. Это работает как шарм.
Это довольно просто и легко понять. Тем не менее, я хотел бы изменить поведение, чтобы отображать ячейку пользователя, которая печатает, просто с "..." внутри, вроде iOS Messenger и Facebook Messenger. Однако у меня есть пара вопросов относительно того, как этого добиться.
Прежде всего: я возвращаю количество ячеек в моем collectionView из messages.count. Должен ли я добавить сообщение к messages.count, когда пользователь печатает?
Во-вторых, я хотел бы удалить эту ячейку, как только пользователь перестал печатать или когда таймер сработал (через 10 секунд). Как я должен сделать это в правильном indexPath? Могу ли я сохранить indexPath, в котором отображается ячейка, а затем удалить его?
Третий и последний: я бы хотел, чтобы эта ячейка всегда была внизу чата. Поэтому, когда другой пользователь вводит сообщение, индикатор ... все равно должен быть внизу. Могу ли я это сделать?
Буду очень признателен за любые идеи или советы, указывающие мне правильное направление! Спасибо, ребята.
РЕДАКТИРОВАТЬ: Размышляя о своем посте, я сейчас обдумываю другой способ: возможно, будет хорошей идеей ввести еще один пользовательский UICollectionViewCell, основанный на ячейках чата, но имеющий только ... внутри него и изменить числоOfItemsInSection на основе isTyping? Примерно так:
if(isTyping) {
return messages.count + 1
} else {
return messages.count
}
Я просто размышляю вслух - пожалуйста, дайте мне знать, что вы, ребята, думаете, или если есть лучшее решение.