From d36568e5ab070c558831e0c53ca6128642f1be0d Mon Sep 17 00:00:00 2001 From: hyouuu Date: Mon, 17 Feb 2020 00:31:52 -0800 Subject: [PATCH 1/4] Add scrollToLastItem --- Sources/Views/MessagesCollectionView.swift | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Sources/Views/MessagesCollectionView.swift b/Sources/Views/MessagesCollectionView.swift index 56cc313a..2658b832 100644 --- a/Sources/Views/MessagesCollectionView.swift +++ b/Sources/Views/MessagesCollectionView.swift @@ -100,8 +100,24 @@ open class MessagesCollectionView: UICollectionView { cell?.handleTapGesture(gesture) } + // NOTE: It's possible for small content size this wouldn't work - https://github.com/MessageKit/MessageKit/issues/725 + public func scrollToLastItem(at pos: UICollectionView.ScrollPosition = .centeredVertically, animated: Bool = true) { + guard numberOfSections > 0 else { return } + + let lastSection = numberOfSections - 1 + let lastItem = numberOfItems(inSection: lastSection) - 1 + + guard lastItem >= 0 else { return } + + let indexPath = IndexPath(row: lastItem, section: lastSection) + scrollToItem(at: indexPath, at: pos, animated: animated) + } + + // NOTE: This method seems to cause crash in certain cases - https://github.com/MessageKit/MessageKit/issues/725 + // Could try using `scrollToLastItem` above public func scrollToBottom(animated: Bool = false) { - performBatchUpdates(nil) { _ in + performBatchUpdates(nil) { [weak self] _ in + guard let self = self else { return } let collectionViewContentHeight = self.collectionViewLayout.collectionViewContentSize.height self.scrollRectToVisible(CGRect(0.0, collectionViewContentHeight - 1.0, 1.0, 1.0), animated: animated) } From a3cb5aeaa60a98c6ef7200ffaa349a2e53aa4c41 Mon Sep 17 00:00:00 2001 From: hyouuu Date: Mon, 17 Feb 2020 00:32:46 -0800 Subject: [PATCH 2/4] Add scrollsToLastItemOnKeyboardBeginsEditing flag --- Sources/Controllers/MessagesViewController.swift | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Sources/Controllers/MessagesViewController.swift b/Sources/Controllers/MessagesViewController.swift index bc4bc00e..982a2df5 100644 --- a/Sources/Controllers/MessagesViewController.swift +++ b/Sources/Controllers/MessagesViewController.swift @@ -36,10 +36,18 @@ UICollectionViewDelegateFlowLayout, UICollectionViewDataSource { /// The `InputBarAccessoryView` used as the `inputAccessoryView` in the view controller. open lazy var messageInputBar = InputBarAccessoryView() + /// A Boolean value that determines whether the `MessagesCollectionView` scrolls to the + /// last item whenever the `InputTextView` begins editing. + /// + /// The default value of this property is `false`. + /// NOTE: This calls scrollToLastItem where as the below flag calls scrollToBottome - check methods for differences + open var scrollsToLastItemOnKeyboardBeginsEditing: Bool = false + /// A Boolean value that determines whether the `MessagesCollectionView` scrolls to the /// bottom whenever the `InputTextView` begins editing. /// /// The default value of this property is `false`. + /// NOTE: This calls scrollToBottome where as the above flag calls scrollToLastItem - check methods for differences open var scrollsToBottomOnKeyboardBeginsEditing: Bool = false /// A Boolean value that determines whether the `MessagesCollectionView` From 4d0350e96c2952a7fb930d449ce56e05a5d8384d Mon Sep 17 00:00:00 2001 From: hyouuu Date: Mon, 17 Feb 2020 00:33:27 -0800 Subject: [PATCH 3/4] Check scrollsToLastItemOnKeyboardBeginsEditing and scroll on begin editing --- .../MessagesViewController+Keyboard.swift | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Sources/Controllers/MessagesViewController+Keyboard.swift b/Sources/Controllers/MessagesViewController+Keyboard.swift index 29b786a1..7ec0be14 100644 --- a/Sources/Controllers/MessagesViewController+Keyboard.swift +++ b/Sources/Controllers/MessagesViewController+Keyboard.swift @@ -45,9 +45,15 @@ internal extension MessagesViewController { @objc private func handleTextViewDidBeginEditing(_ notification: Notification) { - if scrollsToBottomOnKeyboardBeginsEditing { - guard let inputTextView = notification.object as? InputTextView, inputTextView === messageInputBar.inputTextView else { return } - messagesCollectionView.scrollToBottom(animated: true) + if scrollsToLastItemOnKeyboardBeginsEditing || scrollsToBottomOnKeyboardBeginsEditing { + guard let inputTextView = notification.object as? InputTextView, + inputTextView === messageInputBar.inputTextView else { return } + + if scrollsToLastItemOnKeyboardBeginsEditing { + messagesCollectionView.scrollToLastItem() + } else { + messagesCollectionView.scrollToBottom(animated: true) + } } } From d1233de07132dee05fd948f74a37e59bff462839 Mon Sep 17 00:00:00 2001 From: hyouuu Date: Mon, 17 Feb 2020 01:27:07 -0800 Subject: [PATCH 4/4] default pos to bottom --- Sources/Views/MessagesCollectionView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Views/MessagesCollectionView.swift b/Sources/Views/MessagesCollectionView.swift index 2658b832..ce960897 100644 --- a/Sources/Views/MessagesCollectionView.swift +++ b/Sources/Views/MessagesCollectionView.swift @@ -101,7 +101,7 @@ open class MessagesCollectionView: UICollectionView { } // NOTE: It's possible for small content size this wouldn't work - https://github.com/MessageKit/MessageKit/issues/725 - public func scrollToLastItem(at pos: UICollectionView.ScrollPosition = .centeredVertically, animated: Bool = true) { + public func scrollToLastItem(at pos: UICollectionView.ScrollPosition = .bottom, animated: Bool = true) { guard numberOfSections > 0 else { return } let lastSection = numberOfSections - 1