mrd
mrd

Reputation: 4699

How to select item in collectionview programmatically?

I have a UICollectionView. The UICollectionView's datasource is a NSArray of students (from CoreData). I want the current student item be selected/highlighted.

How can I do this? I know there is a method:

- (void)selectItemAtIndexPath:(NSIndexPath *)indexPath 
                     animated:(BOOL)animated 
               scrollPosition:(UICollectionViewScrollPosition)scrollPosition;

which takes as arguments an NSIndexPath and UICollectionViewScrollPosition.

I have the datasource (NSArray of students populated from CoreData) and the student object to be selected.

So, how do I get the NSIndexPath and UICollectionViewScrollPosition? Or is there any other way to highlight an item?

Upvotes: 30

Views: 81056

Answers (9)

AzeTech
AzeTech

Reputation: 697

Swift 5

If you want to set selected 2nd item in an array, then index will be 1 for row 1

 self?.collectionView.selectItem(at: NSIndexPath(row: 1, section: 0) as IndexPath, animated: false, scrollPosition: [])

Upvotes: 0

Ali A. Jalil
Ali A. Jalil

Reputation: 921

SWIFT 5

collView.selectItem(at: NSIndexPath(item: 0, section: 0) as IndexPath, animated: false, scrollPosition: .centeredHorizontally)

Upvotes: 0

Godswill Adie
Godswill Adie

Reputation: 1

With Swift:

You can simply do this to get the index of the collectiveView and use the key to fetch the data from your array

collectionView.indexPathsForSelectedItems?.last?.row

This give you the index of the selected item as an integer

Upvotes: -2

IsPha
IsPha

Reputation: 419

Super late I know, but just for Record, for item x in section y:

 NSIndexPath *indexPath = [NSIndexPath indexPathForItem:x inSection:y];

if you want to just highlight an item programmatically, you need to call selectItemAtIndexPath method on the collection view itself like:

[theCollectionView selectItemAtIndexPath:indexPath
    animated:YES scrollPosition:UICollectionViewScrollPositionCenteredVertically];

if you want to simulate selecting an item programmatically and you get the code in did select gets called, you need to call selectItemAtIndexPath method on the view controller itself and pass to it your collection view as param like:

[theViewController collectionView:theCollectionView didSelectItemAtIndexPath:indexPath];

Now as sure thing, in order to get an item selected and the did select code gets called, you need to call both :D

[theCollectionView selectItemAtIndexPath:indexPath
    animated:YES scrollPosition:UICollectionViewScrollPositionCenteredVertically];

[theViewController collectionView:theCollectionView didSelectItemAtIndexPath:indexPath];

SWIFT version:

let indexPath = IndexPath(item: x, section: y)
theCollectionView.selectItem(at: indexPath, animated: true, scrollPosition: .centeredVertically)
theViewController.collectionView(theCollectionView, didSelectItemAt: indexPath)

enjoy!

Upvotes: 5

user7396942
user7396942

Reputation:

the signature has changes.

didSelectItemAtIndexPath  to didSelectItemAt 

you check this please:

_ collectionView

try with this please:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath){

        print(" selected",)
    }

Upvotes: 1

Krunal
Krunal

Reputation: 79636

Swift

let indexPath = self.collectionView.indexPathsForSelectedItems?.last ?? IndexPath(item: 0, section: 0)
self.collectionView.selectItem(at: indexPath, animated: false, scrollPosition: UICollectionView.ScrollPosition.centeredHorizontally)

Upvotes: 18

Vishal Chaudhari
Vishal Chaudhari

Reputation: 393

let indexPathForFirstRow = IndexPath(row: 0, section: 0)
    paymentHeaderCollectionView.selectItem(at: indexPathForFirstRow, animated: false, scrollPosition: UICollectionViewScrollPosition.left)
    self.collectionView(paymentHeaderCollectionView, didSelectItemAt: indexPathForFirstRow)

Upvotes: 0

Shahin
Shahin

Reputation: 885

You can simply use this after [self.collectionView reloadData]

[self.collectionView 
   selectItemAtIndexPath:[NSIndexPath indexPathForItem:index inSection:0] 
                animated:YES
          scrollPosition:UICollectionViewScrollPositionCenteredVertically];

where index is the index number for the selected student.

Upvotes: 37

sgib
sgib

Reputation: 1040

From your question I'm assuming you only ever have one selected student, I did a similar thing with a collection of icons the user could select. Firstly in view did load I did:

override func viewDidLoad() {
    super.viewDidLoad()

    iconCollectionView.delegate = self
    iconCollectionView.dataSource = self
    iconCollectionView.allowsMultipleSelection = false
    iconCollectionView.selectItemAtIndexPath(NSIndexPath(forItem: 0, inSection: 0), animated: false, scrollPosition: .None)
}

Here I default to selecting the first cell, you would use StudentArray.indexOf to get your selected student index. Then to show the which item is selected I did:

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = iconCollectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! IconCollectionViewCell
    cell.imageView.image = UIImage(named: imageResourceNames.pngImageNames[indexPath.row])
    if cell.selected {
        cell.backgroundColor = UIColor.grayColor()
    }
    return cell
}

This is called when the collection is first displayed, then to react to changes in selection:

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
    collectionView.cellForItemAtIndexPath(indexPath)?.backgroundColor = UIColor.grayColor()
}

func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
    collectionView.cellForItemAtIndexPath(indexPath)?.backgroundColor = UIColor.clearColor()
}

Obviously there are many ways to show cell selection, my way is simple but that's all I needed to do.

EDIT: Since posting the above I have realised it's simpler to just add an observer to selected in the cell class:

class IconCollectionViewCell: UICollectionViewCell {

...

    override var selected: Bool {
        didSet {
            backgroundColor = selected ? UIColor.grayColor() : UIColor.clearColor()
        }
    }
}

With this in place the there is no need to handle didSelect or didDeselect or check for selected in cellForItemAtIndexPath, the cell does it automatically.

Upvotes: 10

Related Questions