Messagekit: [Question] Embedding MessagesViewController in another view controller's view

Created on 22 May 2018  路  8Comments  路  Source: MessageKit/MessageKit

I am trying to embed messaging UI in the hierarchy of other views in another view controller, so messages can overlay over content.

This is how I add it to the view

class ParentViewController: UIViewController {
  //ConversationViewController is subclass of MessagesViewController
  var conversationVC: ConversationViewController = ConversationViewController()
  //...
  viewDidLoad() {
        super.viewDidLoad()
        conversationVC.view.frame = self.view.bounds
        self.view.addSubview(conversationVC.view)
        self.addChildViewController(conversationVC)
        conversationVC.didMove(toParentViewController: self)
  }
}

This loads the messages just fine, but I cant get the messageInputBar to display for the life of me. Is MessageKit designed to be able to be embedded in other view controllers?

question stale

All 8 comments

@wildseansy Inside the viewDidLoad method of your ConversationViewController try calling becomeFirstResponder(). The MessageInputBar is the inputAccessoryView of the controller

Sent with GitHawk

I have tried all of these below in ConversationViewController viewDidLoad:

        self.becomeFirstResponder()
        self.view.becomeFirstResponder()
        self.messageInputBar.inputTextView.becomeFirstResponder()

but still can't see the MessageInputBar. It's worth noting the parent view controller doesn't have any text fields, and is pretty simple. Basically just has one button and some text

@wildseansy Try calling self.becomeFirstResponder() in viewWillLayoutSubviews

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()

        if self.isFirstResponder != true {
            self.becomeFirstResponder()
        }
    }

@joshuaflores - this didn't work, however after following this post, I tried this and it worked. Seems a little hacky tho

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()

        if self.isFirstResponder != true {
            self.perform(
                #selector(becomeFirstResponder),
                with: nil,
                afterDelay: 0.3
            )
        }
    }

@joshuaflores Maybe try the parent view controller instead?

@SD10 @wildseansy the code I posted worked for me, but it did present a few edge cases. Studying the problem some more I think the issue is calling becomeFirstResponder too soon. Really viewWillLayoutSubviews only works because of its position in the life-cycle methods. You should be able to call the same code within viewDidLoad by placing it within a timeout closure.

From my end I simply changed the life-cycle method from 'viewWillLayoutSubviews' toviewDidAppear and it seems to work fine.

    override func viewDidAppear(_ animated: Bool) {
        super.viewWillLayoutSubviews(animated)

        if self.isFirstResponder != true {
            self.becomeFirstResponder()
        }
    }

The only issue now is the inputAccessory not dismissing with the viewController, but that should probably be a different gh issue...

You'll all get better answers if you search on SO for questions related to the inputAccessoryView of a UIViewController. This is not a MessageKit issue but a general iOS question. Just a heads up so you don't constrain yourselves to the scope of GitHub issues

This issue has been marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

brandon-haugen picture brandon-haugen  路  3Comments

ChandraPrakashJangid picture ChandraPrakashJangid  路  3Comments

NiklasWilson picture NiklasWilson  路  4Comments

adri4silva picture adri4silva  路  4Comments

omaralbeik picture omaralbeik  路  4Comments