2017-01-31 3 views
5

Я работаю с JSQMessagesViewController и Firebase, чтобы реализовать функцию чата в моем приложении. В моем ChatViewController все было хорошо. Но теперь я переместил свой ChatViewController в представление контейнера, которое находится внутри родительского контроллера представления, и теперь кнопка «отправить» не работает, когда клавиатура расширяется.InputToolbar Кнопка отправки не работает

Другими словами, чтобы отправить сообщение чата, я должен позвонить 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

Спасибо за вход Dave, но это, похоже, не проблема, границы моего представления контейнера находятся в пределах его родительского представления. Кнопка, о которой я говорю, является частью клавиатуры iOS, это не кнопка, которую я добавил/настроил сам. – MikeG

+0

Является ли кнопка неактивной? Или это реагирует на ваше прикосновение, но не приводит к чему-либо? –

ответ

0

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

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

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

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

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

+0

Можете ли вы добавить пример в Swift о том, как проверить «CGRectGetHeight (keyboardEndFrame)» и 'insets.bottom' для установки дна представления коллекции достаточно места для отображения входного представления в контейнере? У меня возникают трудности. – MikeG

+0

@MikeG проверить мое редактирование – Terence

+0

Хорошо, я использовал точку останова, но я не могу найти значение для' insets.bottom' где угодно. Все, что я вижу, это панель инструментов ввода '_preferredDefaultHeight = 44'. Даже если вы правы, и что-то неправильно вычисляется, то как бы я действительно их исправил? – MikeG

Смежные вопросы