Кнопка ввода InputToolbar не работает

Я работаю с 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) на родительском контроллере представления, а не на самом дочернем представлении. Это заставило меня подумать, что мне нужно настроить действие кнопки в родительском представлении, однако я не добился успеха. Спасибо за вашу помощь

1 ответ

Я предполагаю, что представление коллекции jsq покрывает представление ввода, поэтому вы нажимаете на представление коллекции, а не кнопку отправки. Установить точку останова на - (void)jsq_didReceiveKeyboardWillChangeFrameNotification:(NSNotification *)notification в JSQMessagesViewControllerпроверить, CGRectGetHeight(keyboardEndFrame) а также insets.bottom для настройки представления коллекции внизу достаточно места для отображения входного представления в вашем контейнере. Проблема в том, что контроллер jsq использует autolayout для настройки подпредставлений, представление коллекции совпадает с topLayoutGuide а также bottomLayoutGuide что является контроллером представления, когда вы помещаете контроллер представления в другой контроллер представления, это может вызвать путаницу.

Возьмите, например, iPhone 6(s)/7 plus, высота клавиатуры 271, панель ввода - 44 высоты в контроллере, поэтому общая высота - 315. Поэтому CGRectGetHeight(keyboardEndFrame) + insets.bottom должно быть 315. Поставьте точку останова в этой строке, проверьте, равна ли сумма 315, если нет, это означает, что что-то вычислено неправильно.

Обновление для решения Если причина действительно указана выше, попробуйте решить эту проблему

self.additionalContentInset = UIEdgeInsets(top: 0, left: 0, bottom: 44, right: 0)

Это добавит нижнюю вставку к представлению коллекции. Добавьте это после viewDidLoad

Другие вопросы по тегам