The MessageInputBar is the reactive InputAccessoryView of the MessagesViewController. It has a fairly basic delegate, MessageInputBarDelegate, that can be used to detect when the send button is pressed however its individual InputBarButtonItem's can be individually set up to react to various events.
We recommend viewing the example project for demos on how to make the MessageInputBar look like Facebook Messenger's, Slack's or iMessage.
Why doesn't the MessageInputBar appear in my controller?
If you're using the MessagesViewController as a child view controller then
you have to call becomeFirstResponder() on your view controller. The
reason is because the MessageInputBar is the inputAccessoryView of the
MessagesViewController. This means that it is not in the view hierarchy of
MessagesViewController's root view.
class ParentVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let childVC = MessagesViewController()
addChildViewController(childVC)
self.view.addSubview(childVC.view)
childVC.didMove(toParentViewController:self)
self.becomeFirstResponder()
}
}Q: HELP! All kinds of `UILayoutConstraint`'s are being broken?
// A: Be sure that you are not animating any of the sizing during `viewDidLoad()`. For anything else, try https://www.wtfautolayout.com first
Q: I set the items to the left stack view but I cannot see them?
// A: Remeber to call `func setLeftStackViewWidthConstant(to newValue: CGFloat, animated: Bool)`. A width constraint is required so that the `InputTextView` always spans the width between the left and right stack views
Q: How do I add padding?
// A: There are two `UIEdgeInsets` that manage the padding. There is `padding` and 'textViewPadding`. Note that `textViewPadding.top` does nothing, as if you want to add padding between the top of the `InputTextView` and its superview you would use `padding`/ func messageInputBar(_ inputBar: MessageInputBar, didPressSendButtonWith text: String)
func messageInputBar(_ inputBar: MessageInputBar, didChangeIntrinsicContentTo size: CGSize)
func messageInputBar(_ inputBar: MessageInputBar, textViewTextDidChangeTo text: String)The layout of the MessageInputBar is made of of 3 UIStackView's and an InputTextView (subclass of UITextView). The padding of the subviews can be easily adjusted by changing the padding and textViewPadding properties. The constraints will automatically be updated.
H:|-(padding.left)-[UIStackView(leftStackViewWidthContant)]-(textViewPadding.left)-[InputTextView]-(textViewPadding.right)-[UIStackView(rightStackViewWidthContant)]-(padding.right)-|
V:|-(padding.top)-[InputTextView]-(textViewPadding.bottom)-[UIStackView]-(padding.bottom)-|It is important to note that each of the UIStackView's to the left and right of the InputTextView are anchored by a width constraint. This way the InputTextView will always fill the space inbetween in addition to providing methods that can easily be called to hide all buttons to the right or left of the InputTextView by setting the width constraint constant to 0.
func setLeftStackViewWidthConstant(to newValue: CGFloat, animated: Bool)
func setRightStackViewWidthConstant(to newValue: CGFloat, animated: Bool)It is recommended that you use the InputBarButtonItem for the UIStackView's. This is because all UIStackView's are intitially set with the following properties:
let view = UIStackView()
view.axis = .horizontal
view.distribution = .fill
view.alignment = .fill
view.spacing = 15This will layout the arrangedViews based on their intrinsicContentSize and if there is extra space the views will be expanded based on their content hugging UILayoutPriority.
Each InputBarButtonItem's intrinsicContentSize can be overridden by setting the size property. It is optional so when set to nil the super.intrinsicContentSize will be used.
Spacing can be set using the spacing property. This will change the content hugging UILayoutPriority and add extra space to the intrinsicContentSize when set to .fixed(CGFloat).
Each InputBarButtonItem has properties that can hold actions that will be executed during various hooks such as the button being touched, the InputTextVIew text changing and more! Thanks to these easy hooks with a few lines of code the items can be easily resized and animated similar to that of the Facebook messenger app.
// MARK: - Hooks
public typealias InputBarButtonItemAction = ((InputBarButtonItem) -> Void)
private var onTouchUpInsideAction: InputBarButtonItemAction?
private var onKeyboardEditingBeginsAction: InputBarButtonItemAction?
private var onKeyboardEditingEndsAction: InputBarButtonItemAction?
private var onTextViewDidChangeAction: ((InputBarButtonItem, InputTextView) -> Void)?
private var onSelectedAction: InputBarButtonItemAction?
private var onDeselectedAction: InputBarButtonItemAction?
private var onEnabledAction: InputBarButtonItemAction?
private var onDisabledAction: InputBarButtonItemAction?Contact the components author Nathan Tannar on the Slack channel.
