Пользователь Firebase Chat печатает индикаторную ячейку - PullRequest
0 голосов
/ 30 октября 2018

У меня есть база данных 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
}

Я просто размышляю вслух - пожалуйста, дайте мне знать, что вы, ребята, думаете, или если есть лучшее решение.

1 Ответ

0 голосов
/ 07 ноября 2018

В конце концов исправили его с помощью дополнительного представления (нижнего колонтитула), в котором я изменяю высоту на основе Bool isTyping (установите frame на width & height 0, если не печатаете) и соответственно измените contentInset. Затем, когда изменения isTyping в обозревателе Fitebase, я перезагружаю Data (), чтобы показать или скрыть нижний колонтитул, работает хорошо!

...