UICollectionView automatically scroll to bottom when screen loads
Just to elaborate on my comment.
viewDidLoad is called before elements are visual so certain UI elements cannot be manipulated very well. Things like moving buttons around work but dealing with subviews often does not (like scrolling a CollectionView).
Most of these actions will work best when called in viewWillAppear or viewDidAppear. Here is an except from the Apple docs that points out an important thing to do when overriding either of these methods:
You can override this method to perform additional tasks associated
with presenting the view. If you override this method, you must call
super at some point in your implementation.
The super call is generally called before custom implementations. (so the first line of code inside of the overridden methods).
Scroll UICollectionView to bottom
I have added the lines below to run once the query is complete.
var item = self.collectionView(self.collectionView!, numberOfItemsInSection: 0) - 1
var lastItemIndex = NSIndexPath(forItem: item, inSection: 0)
self.collectionView?.scrollToItemAtIndexPath(lastItemIndex, atScrollPosition: UICollectionViewScrollPosition.Top, animated: false)
Update to Swift 5
let item = self.collectionView(self.collectionView, numberOfItemsInSection: 0) - 1
let lastItemIndex = IndexPath(item: item, section: 0)
self.collectionView.scrollToItem(at: lastItemIndex, at: .top, animated: true)
Can' t scroll to bottom UICollectionview
do you have 2 sections in collectionview?, it this yes ignore my answer, i hope the problem is you are trying to acces a section 1, you just have the section 0 available, try to change this code:
func initMessages() {
DataService.call.retrieveMessages(roomID: room.id ?? "") { (success, error, messages) in
if !success {
print("error", error!.localizedDescription)
} else {
guard let messages = messages else {return}
self.messages = messages
DispatchQueue.main.async {
self.adapter.performUpdates(animated: true, completion: nil)
// Here in section
let indexPath = IndexPath(item: self.messages.count - 1, section: 0)
self.collectionView.scrollToItem(at: indexPath, at: .bottom, animated: true)
}
}
}
}
EDIT:
ok, if the section didn't work try this extension:
extension UICollectionView {
func scrollToLast() {
guard numberOfSections > 0 else {
return
}
let lastSection = numberOfSections - 1
guard numberOfItems(inSection: lastSection) > 0 else {
return
}
let lastItemIndexPath = IndexPath(item: numberOfItems(inSection: lastSection) - 1,
section: lastSection)
scrollToItem(at: lastItemIndexPath, at: .bottom, animated: true)
}
}
usage:
collectionView.scrollToLast()
How to make UICollectionView scroll from bottom for chat application after reload data?
To get the collectionView to populate from the bottom, you can modify the top inset of the collection view as the collectionView reloads,
Call this after calling reloadData():
func updateCollectionContentInset() {
let contentSize = yourCollectionView.collectionViewLayout.collectionViewContentSize
var contentInsetTop = yourCollectionView.bounds.size.height
contentInsetTop -= contentSize.height
if contentInsetTop <= 0 {
contentInsetTop = 0
}
yourCollectionView.contentInset = UIEdgeInsets(top: contentInsetTop,left: 0,bottom: 0,right: 0)
}
Then to scroll to the bottom when you want it to do so (in your data source's didSet after collectionView reload and updating the content inset), call:
func scrollToBottom() {
guard !yourDataSource.isEmpty else { return }
let lastIndex = yourDataSource.count - 1
yourCollectionView.scrollToItem(at: IndexPath(item: lastIndex, section: 0), at: .centeredVertically, animated: true)
}
UICollectionView not scrolling to bottom on the first few items
The problem maybe when the collection view content size is too small, scrollToItem doesn't work properly. Try use this code
func scrollToBottomAnimated(animated: Bool) {
guard self.collectionView.numberOfSections > 0 else{
return
}
let items = self.collectionView.numberOfItems(inSection: 0)
if items == 0 { return }
let collectionViewContentHeight = self.collectionView.collectionViewLayout.collectionViewContentSize.height
let isContentTooSmall: Bool = (collectionViewContentHeight < self.collectionView.bounds.size.height)
if isContentTooSmall {
self.collectionView.scrollRectToVisible(CGRect(x: 0, y: collectionViewContentHeight - 1, width: 1, height: 1), animated: animated)
return
}
self.collectionView.scrollToItem(at: NSIndexPath(item: items - 1, section: 0) as IndexPath, at: .bottom, animated: animated)
}
Related Topics
Coredata Crash Error Xcode 11 Beta, iOS 13 Beta
Get Rawvalue from Enum in a Generic Function
What's the Swift Equivalent of Objective-C's "#Ifdef _Iphone_11_0"
Swiftui: Dismiss View Within MACos Navigationview
Confusion Regarding Overriding Class Properties in Swift
Ios-Charts Library: X-Axis Labels Without Backing Data Not Showing
Why Does My Pfanalytics Not Have Trackappopenewithlaunchoptions Function? (iOS Swift)
Swift 2.0 Constraintswithvisualformat
Present Actionsheet in Swiftui on iPad
Check Availability in Switch Statement
Swift 4.2+ Seeding a Random Number Generator
Resetting Zone Allocator with Allocations Still Alive
Iterate an Array W/ Explicit Object Type in Swift
How to Get the Yaw, Pitch, Roll of an Aranchor in Absolute Terms