diff --git a/Example/Sources/ConversationViewController.swift b/Example/Sources/ConversationViewController.swift index 6d878e83..07566c94 100644 --- a/Example/Sources/ConversationViewController.swift +++ b/Example/Sources/ConversationViewController.swift @@ -28,10 +28,20 @@ import MapKit class ConversationViewController: MessagesViewController { + let refreshControl = UIRefreshControl() + var messageList: [MockMessage] = [] { didSet { - DispatchQueue.main.async { - self.messagesCollectionView.reloadAndMaintainOffset() + if !refreshControl.isRefreshing { + DispatchQueue.main.async { + self.messagesCollectionView.reloadData() + } + } else { + // wait util the refreshing animation is stop + DispatchQueue.main.asyncAfter(deadline: .now() + 1) { + self.messagesCollectionView.reloadDataAndKeepOffset() + self.refreshControl.endRefreshing() + } } } } @@ -58,7 +68,8 @@ class ConversationViewController: MessagesViewController { scrollsToBottomOnFirstLayout = true //default false scrollsToBottomOnKeybordBeginsEditing = true // default false - messageLoadMoreControl.addTarget(self, action: #selector(loadMoreMessages), for: .valueChanged) + messagesCollectionView.addSubview(refreshControl) + refreshControl.addTarget(self, action: #selector(loadMoreMessages), for: .valueChanged) navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(named: "ic_keyboard"), style: .plain, diff --git a/Sources/Controllers/MessagesViewController.swift b/Sources/Controllers/MessagesViewController.swift index 1138989c..0dce29b6 100644 --- a/Sources/Controllers/MessagesViewController.swift +++ b/Sources/Controllers/MessagesViewController.swift @@ -34,10 +34,6 @@ open class MessagesViewController: UIViewController { /// The `MessageInputBar` used as the `inputAccessoryView` in the view controller. open var messageInputBar = MessageInputBar() - open var messageLoadMoreControl: UIRefreshControl { - return messagesCollectionView.messageLoadMoreControl - } - /// A Boolean value that determines whether the `MessagesCollectionView` scrolls to the /// bottom on the view's first layout. /// diff --git a/Sources/Views/MessagesCollectionView.swift b/Sources/Views/MessagesCollectionView.swift index 5a7ac4d4..972ec310 100644 --- a/Sources/Views/MessagesCollectionView.swift +++ b/Sources/Views/MessagesCollectionView.swift @@ -35,8 +35,6 @@ open class MessagesCollectionView: UICollectionView { open weak var messagesLayoutDelegate: MessagesLayoutDelegate? open weak var messageCellDelegate: MessageCellDelegate? - - open var messageLoadMoreControl = UIRefreshControl() open var showsDateHeaderAfterTimeInterval: TimeInterval = 3600 @@ -53,7 +51,6 @@ open class MessagesCollectionView: UICollectionView { public override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) { super.init(frame: frame, collectionViewLayout: layout) backgroundColor = .white - addSubview(messageLoadMoreControl) } required public init?(coder aDecoder: NSCoder) { @@ -71,30 +68,20 @@ open class MessagesCollectionView: UICollectionView { scrollToItem(at: indexPath, at: .bottom, animated: animated) } - public func reloadAndMaintainOffset() { - if !messageLoadMoreControl.isRefreshing { - reloadData() - return - } + public func reloadDataAndKeepOffset() { + // stop scrolling + self.setContentOffset(self.contentOffset, animated: false) - // wait util the refreshing animation is stop - DispatchQueue.main.asyncAfter(deadline: .now() + 1) { - // stop scrolling - self.setContentOffset(self.contentOffset, animated: false) - - // calculate the offset and reloadData - let beforeContentSize = self.contentSize - self.reloadData() - self.layoutIfNeeded() - let afterContentSize = self.contentSize - - // reset the contentOffset after data is updated - self.setContentOffset(CGPoint( - x: self.contentOffset.x + (afterContentSize.width - beforeContentSize.width), - y: self.contentOffset.y + (afterContentSize.height - beforeContentSize.height)), animated: false) - - self.messageLoadMoreControl.endRefreshing() - } + // calculate the offset and reloadData + let beforeContentSize = self.contentSize + self.reloadData() + self.layoutIfNeeded() + let afterContentSize = self.contentSize + + // reset the contentOffset after data is updated + self.setContentOffset(CGPoint( + x: self.contentOffset.x + (afterContentSize.width - beforeContentSize.width), + y: self.contentOffset.y + (afterContentSize.height - beforeContentSize.height)), animated: false) } }