我正在使用 JSQMessagesViewController 和 Firebase 在我的应用程序中实现聊天功能。我的 ChatViewController 中的一切都运行良好。但现在我已将 ChatViewController 移动到父 View Controller 内的容器 View 中,现在“发送”按钮在键盘展开时不起作用。
换句话说,为了发送聊天消息,我必须在本身位于 UITabBarController 中的父 View Controller 上调用 view.endEditing(true)
,然后发送按钮才会起作用.但是只要展开键盘,发送按钮就没有反应。下面是我的 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 Controller 上调用 view.endEditing(true)
而不是在 subview 本身上。这让我觉得我需要在父 View 上配置按钮操作,但是我没有成功。感谢您的帮助
最佳答案
我猜是 jsq Collection View 覆盖了输入 View ,所以你按下的是 Collection View ,而不是发送按钮。在JSQMessagesViewController
中的-(void)jsq_didReceiveKeyboardWillChangeFrameNotification:(NSNotification *)notification
打断点,检查是否有CGRectGetHeight(keyboardEndFrame)
和insets .bottom
用于设置 Collection View 底部是足够的空间来显示容器中的输入 View 。一个问题是 jsq Controller 使用自动布局来调整 subview , Collection View 与其 topLayoutGuide
和 bottomLayoutGuide
对齐,这是 View Controller 的东西,当你放置一个 View Controller 时在另一个 View Controller 中,这可能会导致混淆。
以iPhone 6(s)/7 plus为例,keyboard height是271,controller中的inputtoolbar是44高度,所以总高度是315。所以CGRectGetHeight(keyboardEndFrame) + insets.bottom
应该是315。在那一行打断点,检查总和是否是315,如果不是,说明计算错误。
解决方案更新 如果确实是上面提到的原因,试试这个解决问题
self.additionalContentInset = UIEdgeInsets(top: 0, left: 0, bottom: 44, right: 0)
这将为 Collection View 添加底部插图。在 viewDidLoad
关于ios - InputToolbar 发送按钮不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41966636/