我正在使用JSQMessagesViewController和Firebase在我的应用中实现聊天功能。我的ChatViewController中的一切都运行良好。但是现在我已经将我的ChatViewController移动到父视图控制器内的容器视图中,现在"发送"键盘展开时按钮不起作用。
换句话说,为了发送聊天消息,我必须在父视图控制器上调用view.endEditing(true)
,它本身在UITabBarController中,然后发送按钮将起作用。但只要键盘扩展,发送按钮就不会响应。下面是我的ChatViewController代码...
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) {
...
}
}
我想修复发送按钮,以便用户可以在键盘展开时点击发送。有趣的是,为了解除键盘,我必须在父视图控制器上调用view.endEditing(true)
而不是在子视图本身。这让我觉得我需要在父视图上配置按钮操作,但是我没有取得任何成功。谢谢你的帮助
答案 0 :(得分:0)
我猜是jsq集合视图覆盖输入视图,因此您按下集合视图,而不是发送按钮。在- (void)jsq_didReceiveKeyboardWillChangeFrameNotification:(NSNotification *)notification
的{{1}}上放置一个断点,检查设置集合视图底部的JSQMessagesViewController
和CGRectGetHeight(keyboardEndFrame)
是否足以显示容器中的输入视图。问题是jsq控制器使用autolayout来调整子视图,当你将视图控制器放在另一个视图控制器中时,集合视图与其insets.bottom
和topLayoutGuide
对齐,这是视图控制器的事情,可能会引起混淆。
以iPhone 6(s)/ 7 plus为例,keyboard height为271,inputtoolbar在控制器中为44高度,因此总高度为315.因此bottomLayoutGuide
应为315. Put该行上的断点,检查总和是否为315,如果不是,则表示计算错误。
解决方案更新 如果上面确实提到了原因,请尝试这样来解决问题
CGRectGetHeight(keyboardEndFrame) + insets.bottom
这将为集合视图添加底部插图。在self.additionalContentInset = UIEdgeInsets(top: 0, left: 0, bottom: 44, right: 0)