#swift #uiscrollview #uicollectionview
#swift #uiscrollview #uicollectionview
Вопрос:
Я пытаюсь реализовать добавление новой части информации вверху, когда пользователь прокручивает вверх (чтобы просмотреть историю чата) без каких-либо переходов, как в Telegram, Whatsup и так далее
Вот мой метод
private var toItem: NSIndexPath?
private func addMoreCells () {
if collectionView.contentOffset.y <= 0 {
guard let userChatUid = user?.chatUid else { return }
guard let ownChatUid = UsersManager.sharedInstance.currentChatUID() else { return }
guard let offset = conversation?.messages.count else { return }
ConversationsManager.sharedInstance.getConversationsWithMoreMessagesFor(ownChatUid, recipient: userChatUid, offset: offset - 1, successHandler: { [weak weakSelf = self] (conversations) in
dispatch_async(dispatch_get_main_queue()) {
if let messagesFromServer = conversations.first?.messages, var messages = weakSelf?.conversation?.messages {
for message in messagesFromServer {
if !messages.contains(message) {
messages.append(message)
}
}
messages = messages.sort({$0.time?.compare($1.time!) == .OrderedAscending})
weakSelf?.conversation?.messages = messages
weakSelf?.collectionView.reloadData()
weakSelf?.toItem = NSIndexPath(forItem: (messages.count - messagesFromServer.count), inSection: 0)
if let item = weakSelf?.toItem{
weakSelf?.collectionView.scrollToItemAtIndexPath(item, atScrollPosition: .Top, animated: false)
}
}
}
}, failHandler: { (error) in
print(error)
})
}
}
который запускается из
func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
addMoreCells()
}
В первый раз, когда я прокручиваю страницу вверх, все работает так, как я ожидал (добавляется новая часть, никаких скачков. Я вижу новые данные и могу продолжить прокрутку до верха), но когда я продолжаю прокрутку до верха и добавляются новые данные, они всегда возвращаются в положение, в котором была добавлена первая информация.
Но я ожидаю, что оно должно вернуться к значению messages.count - messagesFromServer.count
. В xCode я вижу, что цифры меняются каждый раз, когда я прокручиваю, но scrollToItemAtIndexPath
не работает должным образом
И каждый раз, когда я прокручиваю вверх и добавляются новые данные, он всегда возвращается на первую позицию, когда была добавлена первая информация.
Кто-нибудь может знать, в чем проблема? Потому что я не могу найти решения, чтобы это исправить.
Ответ №1:
Я решил эту проблему следующим образом:
После того, как reloadData()
я сохраняю contentSize
представление коллекции, после этого я обновляю макет, получаю новый contentSize
и вычитаю их, чтобы получить необходимое смещение для прокрутки до этого места без перехода.
weakSelf?.collectionView.reloadData()
guard let previousContentSize = weakSelf?.collectionView.contentSize else { return }
weakSelf?.collectionView.collectionViewLayout.invalidateLayout()
weakSelf?.collectionView.collectionViewLayout.prepareLayout()
weakSelf?.collectionView.layoutIfNeeded()
guard let newContentSize = weakSelf?.collectionView.contentSize else { return }
print("previous Content Size (previousContentSize) and new Content Size (newContentSize)")
let contentOffset = newContentSize.height - previousContentSize.height
weakSelf?.collectionView.setContentOffset(CGPoint(x: 0.0, y: contentOffset), animated: false)
Я отлично работаю, как и следовало ожидать.