Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scrollToItem isn't working in my CollectionView?

Why scrollToItem isn't working in my CollectionView? I want to work scrollToItem on EnabledID. So what's a problem and how fixed it?

Code:

var dataArray = NSMutableArray() // dataArray is has a data from Database
var EnabledID = Int()

EnabledID = UserDefaults.standard.integer(forKey: "EnabledID")
    
if EnabledID == 0 {
        
    EnabledID = 1
    UserDefaults.standard.set(1, forKey: "EnabledID")
        
} else {
    if EnabledID < dataArray.count {
        let index = NSIndexPath(item: EnabledID, section: 0)
        self.myCollectionView.scrollToItem(at: index as IndexPath, at: .centeredVertically, animated: true)
    }
}
    
like image 544
developer1996 Avatar asked Jun 20 '18 11:06

developer1996


6 Answers

try this code...

[collectionView setDelegate:self];
[collectionView reloadData];
[collectionView layoutIfNeeded];
[collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] atScrollPosition:UICollectionViewScrollPositionTop animated:YES];

Swift - 4.x

collectionView.delegate = self
collectionView.reloadData()
collectionView.layoutIfNeeded()
collectionView.scrollToItem(at: IndexPath(item: 0, section: 0), at: .top, animated: true)

When the scroll direction is horizontal you need to use left,right or centeredHorizontally.

top is for the vertical direction.

collectionView.scrollToItem(at: index, at: .top, animated: true)
like image 113
Ramkumar Paulraj Avatar answered Oct 26 '22 15:10

Ramkumar Paulraj


the best way i found to do this is to not use scrollToItem but to get the CGRect of the index and then make that visible.

 let rect = self.collectionView.layoutAttributesForItem(at: IndexPath(row: 5, section: 0))?.frame
 self.collectionView.scrollRectToVisible(rect!, animated: false)
like image 31
tal marom Avatar answered Oct 26 '22 13:10

tal marom


My problem is a little weird. My iPhone 6/7/8 works fine, but iPhone X or 11 cannot scroll to my expected position. My original code is :

collectionView.reloadData()
collectionView.scrollToItem(at: IndexPath(item: 10, section: 0), at: .top, animated: true)

After I add collectionView.layoutIfNeeded(). Problem solves on my iPhone X and 11.

collectionView.reloadData()
collectionView.layoutIfNeeded()
collectionView.scrollToItem(at: IndexPath(item: 10, section: 0), at: .top, animated: true)

This answer is inspired by @ram. He should get the credit. Add this answer is just to emphasize the difference between different iPhones. So people can search their answer quicker.

like image 39
Wu Yuan Chun Avatar answered Oct 26 '22 14:10

Wu Yuan Chun


It won't work because contentSize is probably (0,0). If you not wish to use layoutIfNeeded() (because maybe you could be performing some undesirable an unnecessary stuff there), you should calculate it yourself (assuming your data is loaded, and the view did layout).

Swift 5.2

    collection.contentSize = CGSize(width: collection.bounds.width * CGFloat(items.count), height: collection.bounds.height)
    collection.scrollToItem(at: IndexPath(row: startingIndex, section: 0), at: .left, animated: false)
like image 43
Federico Picci Avatar answered Oct 26 '22 15:10

Federico Picci


Try this for horizontal collection view

var isViewDidLayoutCallFirstTime = true


override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    guard self.isViewDidLayoutCallFirstTime else {return}
    self.isViewDidLayoutCallFirstTime = false
    self.collectionView.collectionViewLayout.collectionViewContentSize // It will required to re calculate collectionViewContentSize in internal method 
    let indexpath = IndexPath(item: self.currentIndex, section: 0)

    self.collectionView.scrollToItem(at: indexpath, at: UICollectionViewScrollPosition.centeredHorizontally, animated: false)

}
like image 29
Prashant Tukadiya Avatar answered Oct 26 '22 13:10

Prashant Tukadiya


I've encountered this issue on iOS 14.x and Xcode 12.x.

The solution that worked for me was to use:

collectionView.scrollRectToVisible(rect, animated: true)
like image 34
Andrei Traciu Avatar answered Oct 26 '22 15:10

Andrei Traciu