I am working with JSQMessagesViewController and Firebase to implement a chat feature in my app. I had everything working well in my ChatViewController. But now I have moved my ChatViewController into a container view that is within a parent view controller and now the "send" button does not work when the keyboard is expanded.
In other words, in order to send a chat message, I must call view.endEditing(true)
on the parent view controller that itself is within a UITabBarController, and then the send button will work. But as long as the keyboard is expanded, the send button doesn't respond. below is my ChatViewController code...
import Foundation
import UIKit
import FirebaseDatabase
import JSQMessagesViewController
final class ChatViewController: JSQMessagesViewController {
var outgoingBubbleImageView: JSQMessagesBubbleImage!
var incomingBubbleImageView: JSQMessagesBubbleImage!
var fireRootRef: FIRDatabaseReference!
var chatMessages = [JSQMessage]()
var messagesRefHandle: UInt!
var chatChannelId: String!
override func viewDidLoad(){
super.viewDidLoad()
self.inputToolbar.contentView.textView.backgroundColor = UIColor.clear
inputToolbar.alpha = 0.7
...
}
override func viewWillAppear(_ animated: Bool){
super.viewWillAppear(animated)
}
override func viewDidAppear(_ animated: Bool){
super.viewDidAppear(animated)
}
func setupView(){
...
}
override func viewWillDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
removeChatObserver()
}
func removeChatObserver(){
...
}
private func setupMessageBubbles() {
...
}
override func collectionView(_ collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return chatMessages.count
}
override func collectionView(_ collectionView: JSQMessagesCollectionView!, messageBubbleImageDataForItemAt indexPath: IndexPath!) -> JSQMessageBubbleImageDataSource! {
let message = chatMessages[indexPath.item]
if message.senderId == senderId {
return outgoingBubbleImageView
} else {
return incomingBubbleImageView
}
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = super.collectionView(collectionView, cellForItemAt: indexPath) as! JSQMessagesCollectionViewCell
let message = chatMessages[indexPath.item]
if message.senderId == senderId {
cell.textView!.textColor = UIColor.white
} else {
cell.textView!.textColor = UIColor.black
}
return cell
}
override func collectionView(_ collectionView: JSQMessagesCollectionView!, layout collectionViewLayout: JSQMessagesCollectionViewFlowLayout!, heightForMessageBubbleTopLabelAt indexPath: IndexPath!) -> CGFloat {
let message = chatMessages[indexPath.item]
if message.senderId == self.senderId {
return 0
}
if indexPath.item > 0 {
let previousMessage = chatMessages[indexPath.item - 1]
if previousMessage.senderId == message.senderId {
return 0
}
}
return kJSQMessagesCollectionViewCellLabelHeightDefault
}
override func collectionView(_ collectionView: JSQMessagesCollectionView!, attributedTextForMessageBubbleTopLabelAt indexPath: IndexPath!) -> NSAttributedString! {
let message = chatMessages[indexPath.item]
switch message.senderId {
case senderId:
return nil
default:
guard let senderDisplayName = message.senderDisplayName else {
assertionFailure()
return nil
}
return NSAttributedString(string: senderDisplayName)
}
}
//no avatar images
override func collectionView(_ collectionView: JSQMessagesCollectionView!, avatarImageDataForItemAt indexPath: IndexPath!) -> JSQMessageAvatarImageDataSource! {
return nil
}
override func didPressSend(_ button: UIButton!, withMessageText text: String!, senderId: String!, senderDisplayName: String!, date: Date!) {
print("DID PRESS SEND")
let fireMessagesRef = fireRootRef.child("messages").child(chatChannelId)
let itemRef = fireMessagesRef.childByAutoId()
let messageItem = [
"text": text,
K.MessageKeys.senderIdKey: senderId,
"displayName": senderDisplayName,
]
itemRef.setValue(messageItem)
JSQSystemSoundPlayer.jsq_playMessageSentSound()
finishSendingMessage()
}
override func didPressAccessoryButton(_ sender: UIButton!) {
//
}
private func observeMessages() {
...
}
func addMessage(id: String, text: String, name: String) {
...
}
}
I would like to fix the send button so the user can tap send when the keyboard is expanded. It is interesting that in order to dismiss the keyboard I have to call view.endEditing(true)
on the parent view controller and not on the child view itself. This made me think that I need to configure the button action on the parent view however i haven't had any success. Thanks for your help