Class
MessagesViewController
open class MessagesViewController:
MessageKit.MessagesViewController,
MessageKit.MessagesDataSource,
MessageKit.MessagesDisplayDelegate,
MessageKit.MessagesLayoutDelegate,
InputBarAccessoryViewDelegate,
MessageKit.MessageCellDelegate,
QLPreviewControllerDataSource,
QLPreviewControllerDelegate,
UIImagePickerControllerDelegate,
UINavigationControllerDelegate,
UICollectionViewDataSourcePrefetching
A ViewController subclass for displaying conversation interfaces.
Prefer to use the make
factory method to init
.
Relationships
Nested Types
MessagesViewController.AvatarOptions
Used to enable/disable the avatar on either side.
MessagesViewController.AttachmentOptions
Used to enable/disable the attachment types you want to support for sending.
Conforms To
InputBarAccessoryViewDelegate
MessageKit.MessageCellDelegate
MessageKit.MessagesDataSource
MessageKit.MessagesDisplayDelegate
MessageKit.MessagesLayoutDelegate
MessageKit.MessagesViewController
QLPreviewControllerDataSource
QLPreviewControllerDelegate
UICollectionViewDataSourcePrefetching
UIImagePickerControllerDelegate
UINavigationControllerDelegate
Nested Type Aliases
SendMessageClosure
public typealias SendMessageClosure = (
_ messages: [MessageType],
_ completion: @escaping (_ failedMessages: [MessageType]
) -> Void) -> Void
The closure that will be called when a message needs to be sent.
This closure will be passed an array of MessageTypes that need to be sent, and a completion closure that you should call when the messages have finished sending. Call the completion closure with the messages that failed. This tells the controller which messages didn't send and will update the UI appropriately.
Parameters
Name | Type | Description |
---|---|---|
messages | An array of MessageTypes that need to be sent. This will almost always be a single message, but may become multiple in the future. |
|
completion | The closure that you need to call with the messages that failed to send. |
|
failedMessages | An array of the MessageTypes that failed to send. |
Initializers
init(currentSender:messages:showsRelativeDaySections:title:sendMessage:resendFailedMessage:)
public init(currentSender: Sender, messages: [MessageType] = [],
showsRelativeDaySections: Bool = true,
title: String = "Chat".localizedCapitalized,
sendMessage: @escaping SendMessageClosure,
resendFailedMessage: ((FailedMessage, @escaping (Bool) -> Void) -> Void)? = nil)
Creates a new MessagesViewController.
Parameters
Name | Type | Description |
---|---|---|
currentSender | Sender |
The current user as a Sender. |
messages | [MessageType] |
An array of messages to pre-fill the controller with. |
showsRelativeDaySections | Bool |
true by default. When true, sections will be inserted to split the messages by day. |
title | String |
The title to display in the navigation bar. |
sendMessage | @escaping SendMessageClosure |
The closure that will be called when a message needs to be sent. This will send you an array of MessageTypes that you should send. Call the completion closure with the failed messages to update the UI. You should only call the completion once. Called on a background thread. |
resendFailedMessage | ((FailedMessage, @escaping (Bool) -> Void) -> Void)? |
The closure that will be called when a failed message needs to be re-sent. Ensure to call the completion closure passing true if the message sent successfully, or false if it failed to send. You should only call the completion closure once. This closure will call the completion block with false by default. Called on a background thread. |
init?(coder:)
@available(*, unavailable, message: "MessagesViewController does not support NSCoding")
public required init?(coder: NSCoder)
MessagesViewController
does not support NSCoding
.
Properties
placeholder
public var placeholder: String = "Type your message here..."
The placeholder to display in the input bar.
allowSending
public var allowSending: Bool = true
Set to false if you want to disable text input and sending
enabledAvatars
public var enabledAvatars: AvatarOptions = []
Set the avatars you want displayed.
Pass []
if you want none enabled. By default, none are shown.
supportedAttachments
public var supportedAttachments: Set<AttachmentOptions> = []
Set the attachment types you'd like to support.
Pass []
if you want non enabled. By default, none are supported.
showsRelativeDaySections
public var showsRelativeDaySections: Bool = true
If true, the controller will automatically insert Relative Day sections (Today, Yesterday)
header
public private(set) var header: Component<MessagesHeaderLayout>?
avatarForMessage
public var avatarForMessage: (MessageType, @escaping (AvatarConfiguration?) -> Void) -> Void
Called when the controller needs an Avatar for a message. Use the completion block to send back the Avatar. You can send back nil if you prefer to use the default placeholder image. Called on a background thread.
resendFailedMessage
public var resendFailedMessage: (FailedMessage, @escaping (Bool) -> Void) -> Void
Called when the controller attempts to resend a failed message. Use this to send the message and call the completion closure when it's re-sent. If it fails to resend, still call the completion closure, but pass false.
prefetchOlderMessages
public var prefetchOlderMessages: (_ completion: @escaping ([MessageType]) -> Void) -> Void
A closure type that will be called when the user scrolls to the top of the list and the controller wants to load more messages. You should set this closure if you need to support backward pagination.
When this is called, you should fetch the messages that should be inserted, then call the completion block with the MessageTypes to insert into the list.
didScroll
public var didScroll: ((_ scrollView: UIScrollView) -> Void)?
didEndDecelerating
public var didEndDecelerating: ((_ scrollView: UIScrollView) -> Void)?
cellForItemAtIndexPath
public var cellForItemAtIndexPath: ((_ collectionView: UICollectionView, _ indexPath: IndexPath) -> Void)?
This will be called when the delegate method collectionView(_ collectionView:cellForItemAt:)
is called
before the cell is returned by a call to the super
implementation of this method.
loadImage
public var loadImage: ((_ url: URL, _ completion: @escaping ((UIImage) -> Void)) -> Void)?
This will be called when the controller need to load an image from a URL for a message.
This can be ignored if you're not using ImageMessages that load from a URL.
willDisplayItem
public var willDisplayItem: ((_ message: MessageType) -> Void)?
This will be called when the delegate method collectionView(_ collectionView:willDisplay:forItemAt:)
is called
You can use this method for doing something like sending an updated read status to the API.
tappableHandler
public var tappableHandler: ((_ tappableValue: String) -> Void)?
This will be called for messages of kind .attributedString
that contain a tappable
attribute.
downloadAttachment
public var downloadAttachment: ((MessageAttachment, @escaping (Data, UINavigationController) -> Void) -> Void)?
This will be called for messages that contain a MessageAttachment. You should download the attachment and present it.
preferredStatusBarStyle
public override var preferredStatusBarStyle: UIStatusBarStyle
isLastSectionVisible
var isLastSectionVisible: Bool
true if the last section is visible, otherwise false.
Methods
make(currentSender:messages:showsRelativeDaySections:title:sendMessage:resendFailedMessage:)
public static func make(currentSender: Sender, messages: [MessageType] = [],
showsRelativeDaySections: Bool = true,
title: String = "Chat".localizedCapitalized,
sendMessage: @escaping SendMessageClosure,
resendFailedMessage: ((FailedMessage, @escaping (Bool) -> Void) -> Void)? = nil) -> MessagesViewController
Creates a new MessagesViewController.
Parameters
Name | Type | Description |
---|---|---|
currentSender | Sender |
The current user as a Sender. |
messages | [MessageType] |
An array of messages to pre-fill the controller with. |
showsRelativeDaySections | Bool |
true by default. When true, sections will be inserted to split the messages by day. |
title | String |
The title to display in the navigation bar. |
sendMessage | @escaping SendMessageClosure |
The closure that will be called when a message needs to be sent. This will send you an array of MessageTypes that you should send. Call the completion closure with the failed messages to update the UI. You should only call the completion once. Called on a background thread. |
resendFailedMessage | ((FailedMessage, @escaping (Bool) -> Void) -> Void)? |
The closure that will be called when a failed message needs to be re-sent. Ensure to call the completion closure passing true if the message sent successfully, or false if it failed to send. You should only call the completion closure once. This closure will call the completion block with false by default. Called on a background thread. |
viewDidLoad()
open override func viewDidLoad()
viewWillAppear(_:)
open override func viewWillAppear(_ animated: Bool)
viewDidAppear(_:)
open override func viewDidAppear(_ animated: Bool)
traitCollectionDidChange(_:)
open override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?)
scrollViewDidScroll(_:)
open func scrollViewDidScroll(_ scrollView: UIScrollView)
scrollViewDidEndDecelerating(_:)
open func scrollViewDidEndDecelerating(_ scrollView: UIScrollView)
collectionView(_:cellForItemAt:)
open override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
collectionView(_:willDisplay:forItemAt:)
open override func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath)
didTapMessage(in:)
open func didTapMessage(in cell: MessageCollectionViewCell)
gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:)
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool
addHeader(configuration:)
@discardableResult
func addHeader(configuration: MessagesHeaderLayout.Configuration) -> Component<MessagesHeaderLayout>
Adds a header to the controller.
Ensure you only call this once. It's a programmer error to call this multiple times.
addConversationStarter(config:)
func addConversationStarter(config: ConversationStarter.Configuration)
Adds a ConversationStarter to the controller.
You should call this method when you create the controller if you need it. It's safe to call this even if you know there are messages in the thread. If you instantiate this controller with messages, the controller will not show this. The controller will also hide this once messages do populate, either if you add messages yourself or if the user sends a message.
It's also safe to call this even when using an availability banner.
addAvailabilityBanner(title:text:)
func addAvailabilityBanner(title: String, text: String? = nil)
Adds an AvailabilityBanner to the controller.
You should call this method the second you know the receiver is unavailable if you need to show an
availability banner; ideally you'd know if the receiver is unavailable before creating this controller.
It's safe to call this method even if you previously called addConversationStarter(config:)
.
The controller will manage the availability banner and conversation starter appropriately.
removeOverlays()
func removeOverlays()
Removes overlays such as the conversation starter and the availability banner. This will be called when a message is asked to send.
showAttachmentSheet()
func showAttachmentSheet()
Displays the attachment sheet. If the supportedAttachments
property is empty, this will do nothing.
showCameraOrPhotoLibrarySheet()
func showCameraOrPhotoLibrarySheet()
insertMessage(_:)
func insertMessage(_ message: MessageType)
Inserts a new message into the controller.
You should call this method when you've received a message and need to insert it into the UI. The controller also uses this method to insert sent messages into the UI.
Parameters
Name | Type | Description |
---|---|---|
message | MessageType |
The MessageType to insert into the collection. |
prependMessages(_:)
func prependMessages(_ messages: [MessageType])
currentSender()
func currentSender() -> SenderType
The SenderType object that is currently set as the sender for this instance.
Returns
The current sender.
numberOfSections(in:)
func numberOfSections(in messagesCollectionView: MessagesCollectionView) -> Int
messageForItem(at:in:)
func messageForItem(at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> MessageType
messageTimestampLabelAttributedText(for:at:)
func messageTimestampLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString?
messageTopLabelAttributedText(for:at:)
func messageTopLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString?
messageBottomLabelAttributedText(for:at:)
func messageBottomLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString?
messageTopLabelHeight(for:at:in:)
func messageTopLabelHeight(
for message: MessageType,
at indexPath: IndexPath,
in messagesCollectionView: MessagesCollectionView
) -> CGFloat
messageBottomLabelHeight(for:at:in:)
func messageBottomLabelHeight(
for message: MessageType,
at indexPath: IndexPath,
in messagesCollectionView: MessagesCollectionView
) -> CGFloat
configureMediaMessageImageView(_:for:at:in:)
func configureMediaMessageImageView(
_ imageView: UIImageView,
for message: MessageType,
at indexPath: IndexPath,
in messagesCollectionView: MessagesCollectionView
)
customCell(for:at:in:)
func customCell(
for message: MessageType,
at indexPath: IndexPath,
in messagesCollectionView: MessagesCollectionView
) -> UICollectionViewCell
collectionView(_:prefetchItemsAt:)
open func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath])
inputBar(_:didPressSendButtonWith:)
@objc func inputBar(_ inputBar: InputBarAccessoryView, didPressSendButtonWith text: String)
processInputBar(_:)
func processInputBar(_ inputBar: InputBarAccessoryView)
configureAvatarView(_:for:at:in:)
func configureAvatarView(
_ avatarView: MessageAvatar,
for message: MessageType,
at indexPath: IndexPath,
in messagesCollectionView: MessagesCollectionView
)
didTapImage(in:)
func didTapImage(in cell: MessageCollectionViewCell)
didTapMessageBottomLabel(in:)
func didTapMessageBottomLabel(in cell: MessageCollectionViewCell)
backgroundColor(for:at:in:)
func backgroundColor(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> UIColor
textColor(for:at:in:)
func textColor(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> UIColor
messageStyle(for:at:in:)
func messageStyle(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> MessageStyle
numberOfPreviewItems(in:)
public func numberOfPreviewItems(in controller: QLPreviewController) -> Int
previewController(_:previewItemAt:)
public func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem
previewController(_:transitionViewFor:)
public func previewController(_ controller: QLPreviewController, transitionViewFor item: QLPreviewItem) -> UIView?