MessageKit: MessageInputBar not showing when MessagesViewController subclass used as ChildViewController

MessageKit Version: 1.0.0 Swift Version: 4.1 Test Device: iPad 12.9(inch)

When adding messageViewController on container view(red color background), seems like inputAccesoryView doesn’t show.

screen shot 2018-06-22 at 13 56 55

I tried to use becomFirstResponder in viewdidAppear but the inputAccesoryView seems to take width of the parentViewController (here you can see the code):

override func viewDidLoad() {
    super.viewDidLoad()
    setupNavigationBar(actionsTarget: self)
    setupLocalization()
    
    viewController = ChatViewController()
    addChildViewController(viewController!)
    viewController?.view.frame = containerView.bounds
    containerView.addSubview((viewController?.view)!)
    viewController?.didMove(toParentViewController: self)
     
  }
  
  override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    viewController?.becomeFirstResponder()
  }
screen shot 2018-06-22 at 13 57 34

Is there a way to make inputAccesoryView to be same width as containerView ?

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 1
  • Comments: 16 (7 by maintainers)

Most upvoted comments

I had the same problem with an InputAccesoryView in a containerView’s childviewcontroller, and what worked for me was setting the “.becomeFirstResponder()” method after all the animations for showing the other viewcontroller were done.

So in my case I was grabbing some Firebase data and setting it in a UITableView in the containerView’s Viewcontroller with an animation when the loading was done, the only thing I need to do was adding (or using the existing) completion handler of that “UIView.animate” and setting it to become the first responder. In my case in my conainerView’s Viewcontroller, it was something like this:

    tableViewHeightConstraint.constant = commentTV.contentSize.height

    UIView.animate(withDuration: 0.4, animations: {
        self.view.updateConstraints()
        self.view.layoutIfNeeded()
    }) { (completed) in
        self.becomeFirstResponder()
    }

I hope it can maybe help you guys out as well, because I was messing around with this for a while now and could’t find any real solution untill I saw this answer on StackOverflow: https://stackoverflow.com/questions/30692899/display-inputaccessoryview-in-childviewcontroller

In order to do this, I had to override the default behavior in the MessagesViewController. I also had to change the default access control for these methods of the MessagesViewController from private to open. I have the files copied into a folder in my project as opposed to some other method of dependency management such as carthage or cocoapods.

    override var hidesBottomBarWhenPushed: Bool {
        get { return true }
        set {}
    }

    override var inputAccessoryView: UIView? {
        return nil
    }

    override func setupSubviews() {
        super.setupSubviews()

        view.addSubview(messageInputBar)
    }

    override func setupConstraints() {

        messagesCollectionView.translatesAutoresizingMaskIntoConstraints = false

        let top = messagesCollectionView.topAnchor.constraint(equalTo: view.topAnchor, constant: topLayoutGuide.length)
        if #available(iOS 11.0, *) {
            let leading = messagesCollectionView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor)
            let trailing = messagesCollectionView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor)
            NSLayoutConstraint.activate([top, trailing, leading])
        } else {
            let leading = messagesCollectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor)
            let trailing = messagesCollectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
            NSLayoutConstraint.activate([top, trailing, leading])
        }

        messageInputBar.translatesAutoresizingMaskIntoConstraints = false

        let messagesBottom = messagesCollectionView.bottomAnchor.constraint(equalTo: messageInputBar.topAnchor)
        if #available(iOS 11.0, *) {
            let mesaageInputBarBottom = messageInputBar.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
            let messageInputBarLeading = messageInputBar.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor)
            let messageInputBarTrailing = messageInputBar.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor)
            NSLayoutConstraint.activate([messagesBottom, mesaageInputBarBottom, messageInputBarLeading, messageInputBarTrailing])
        } else {
            let mesaageInputBarBottom = messageInputBar.bottomAnchor.constraint(equalTo: view.bottomAnchor)
            let messageInputBarLeading = messageInputBar.leadingAnchor.constraint(equalTo: view.leadingAnchor)
            let messageInputBarTrailing = messageInputBar.trailingAnchor.constraint(equalTo: view.trailingAnchor)
            NSLayoutConstraint.activate([messagesBottom, mesaageInputBarBottom, messageInputBarLeading, messageInputBarTrailing])
        }
    }

This should be fixed in 4.0.0

Really what I want to do is add the MessageInputBar as a subview of the MessagesViewController instead of as the inputAccessoryView. Preferably in a way that I can override the default behavior in me MessagesViewController subclass.

@simformsolutions Tge MessagesViewController needs to be the first responder. This is what’s required by UIKit for the InputAccessoryView to show.

Sent with GitHawk

Closing as a duplicate of #296

Hi @VadimPlasiciucShopToMeIOS, as of now there is no way to keep it within the width of the container view due to how InputAccessoryView works. I am working on an alternative that will be released in 2.0 under the new MessageKit/MessageInputBar library

Sent with GitHawk