Can't select item in UICollectionView programmatically

11,727

Solution 1

didSelectItemAt is not called if you call selectItem programmatically. You should call the method manually after it.

self.collectionView.selectItem(at: IndexPath(item: 0, section: 0), animated: true, scrollPosition: .bottom)
self.collectionView(self.collectionView, didSelectItemAt: IndexPath(item: 0, section: 0))

Solution 2

From documentation of selectItem(at:animated:scrollPosition:)

This method does not cause any selection-related delegate methods to be called.

That means you will have to call the delegate method manually.

Solution 3

let indexPath = IndexPath(item: 0, section: 0)
DispatchQueue.main.async {
   self.collectionView.selectItem(at: indexPath, animated: true, scrollPosition: .left)
}

This is the solution which is working for me. Hope this will help you.

Solution 4

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

self.activityCollectionView?.scrollToItem(at: IndexPath(row: 1, section: 0), at: UICollectionViewScrollPosition.right, animated: true)

}

//viewDidAppear is the key

Solution 5

For my case, I need to combine Tamàs and iDev750's answer:

DispatchQueue.main.async {
    self.collectionView.selectItem(at: IndexPath(item: 0, section: 0), animated: true, scrollPosition: .bottom)
    self.collectionView(self.collectionView, didSelectItemAt: IndexPath(item: 0, section: 0))
}
Share:
11,727
David Luque
Author by

David Luque

Updated on June 16, 2022

Comments

  • David Luque
    David Luque about 2 years

    I'm trying to set a default item when the view is loaded this way:

    override func viewDidLoad() {
       super.viewDidLoad()
    
       self.collectionView.delegate = self
       self.collectionView.dataSource = self
       self.collectionView.allowsSelection = true
       self.collectionView.allowsMultipleSelection = true
    
    }
    

    I'm trying to select an item in the viewDidAppear method:

    override func viewDidAppear(_ animated: Bool) {
        DispatchQueue.main.async(execute: {
            self.collectionView.selectItem(at: IndexPath(item: 0, section: 0), animated: true, scrollPosition: UICollectionViewScrollPosition.bottom)
        })
    }
    

    But the didSelectItemAt method is not fired like I need.

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath){
       //some config
    }
    

    Am I forgetting something?

  • Esmaeil
    Esmaeil over 4 years
    When I call it without DipatchQueue.main.async, didSelectItemAt function called but collectionView.cellForItem(at: indexPath) return nil.
  • Radu Ursache
    Radu Ursache over 2 years
    Calling self.collectionView.reloadItems(at: [indexPath]) might be better because off-screen cells will probably crash your app. It depends on the logic of your cells, though