Josip Bogdan
Josip Bogdan

Reputation: 588

How to get cell atIndex in UICollectionView with swift?

I am making Collection view programatically. Here is the code in viewDidLoad func

let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
    layout.sectionInset = UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20)
    layout.itemSize = CGSize(width: 90, height: 120)
    collectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
    collectionView!.dataSource = self
    collectionView!.delegate = self
    collectionView!.registerClass(CollectionViewCell.self, forCellWithReuseIdentifier: "CollectionViewCell")
    collectionView!.layer.cornerRadius = 2
    collectionView!.backgroundColor = UIColor.redColor()
    self.containerView.addSubview(collectionView!)

And these are my collection view functions

func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
    return 1
}

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 8
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionViewCell", forIndexPath: indexPath) as! CollectionViewCell
    cell.backgroundColor = UIColor.blackColor()
    cell.buttonView.addTarget(self, action: Selector("Action\(indexPath.row):"), forControlEvents: UIControlEvents.TouchUpInside)
    return cell
}

Idea is I have a button in the cell, and when I press it the cell should change color, here is the action function

func Action0(sender: UIButton!) {
    var indexPath = NSIndexPath(forRow: 0, inSection: 0)
    let cell = collectionView!.dequeueReusableCellWithReuseIdentifier("CollectionViewCell", forIndexPath: indexPath ) as! CollectionViewCell
    cell.backgroundColor = UIColor.blueColor()

and this is collectionViewCell class,

class CollectionViewCell: UICollectionViewCell {

required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

var buttonView: UIButton!
override init(frame: CGRect) {
    super.init(frame: frame)

    buttonView = UIButton.buttonWithType(UIButtonType.System) as! UIButton
    buttonView.frame = CGRect(x: 0, y: 16, width: frame.size.width, height: frame.size.height*2/3)

    contentView.addSubview(buttonView)
}

}

The button and the action works but the cell doesn't change colour, i guess the problem is in this line

let cell = collectionView!.dequeueReusableCellWithReuseIdentifier("CollectionViewCell", forIndexPath: indexPath ) as! CollectionViewCell

Upvotes: 27

Views: 78738

Answers (6)

mubin
mubin

Reputation: 11

if the cell is present in view then first condition will match otherwise else will call

 let indexPath = IndexPath(item: 0, section: 0);  
    if let customCell = myCollectionView.cellForItem(at: indexPath) as? CustomCell {   
        customCell.nameLabel.text = "some text"
    }else {
    if let customCell = myCollectionView.dequeueReusableCellWithReuseIdentifier("CustomCell", forIndexPath: indexPath) as? CustomCell {
        customCell.nameLabel.text = "some text"
    }

Upvotes: 0

christostsang
christostsang

Reputation: 1841

Works on Swift 5.5 and iOS 15

Adding on Lakhdeep Singh answer, if you want to have access to a specific cell's properties you need to cast it as the cell you want (ex. CustomCell). For instance, if this CustomCell has a nameLabel, you can access it like so:

let indexPath = IndexPath(item: 3, section: 0);  
if let customCell = myCollectionView .cellForItem(at: indexPath) as? CustomCell {   
    customCell.nameLabel.text = "some text"
}  

Upvotes: 5

benhameen
benhameen

Reputation: 1428

This is the way to get the cell at a given indexPath:

let cell = collectionView!.cellForItemAtIndexPath(indexPath)

However, you also might want to try:

cell.contentView.backgroundColor = UIColor.blueColor()

NOTE:

Though the above may have worked, I want to encourage you to try a different implementation to achieve the same functionality. Your implementation would require you to have a separate Action# function for each CollectionViewCell, as well as create the indexPath manually in each of those methods, when you could potentially only have one!

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionViewCell", forIndexPath: indexPath) as! CollectionViewCell
    cell.backgroundColor = UIColor.blackColor()
    cell.buttonView.addTarget(self, action: Selector("action"), forControlEvents: UIControlEvents.TouchUpInside)
    return cell
}

and the function for that one method would be something like:

func action(sender: UIButton!) {
    var point : CGPoint = sender.convertPoint(CGPointZero, toView:collectionView)
    var indexPath = collectionView!.indexPathForItemAtPoint(point)
    let cell = collectionView!.cellForItemAtIndexPath(indexPath)
    cell.backgroundColor = UIColor.blueColor()
}

Updated action function for Swift 4.2

@objc func action(sender: Any){
    print("tickedOffPressed !")
    if let button = sender as? UIButton {
        let point: CGPoint = button.convert(.zero, to: collectionView)
        if let indexPath = collectionView!.indexPathForItem(at: point) {
            let cell = collectionView!.cellForItem(at: indexPath)
            cell?.backgroundColor = UIColor.blue
        }
    }
}

Just a suggestion! Happy coding! :)

Upvotes: 68

Lakhdeep Singh
Lakhdeep Singh

Reputation: 1250

In Swift 4 you can get the cell of CollectionView with:

let indexPath = IndexPath(item: 3, section: 0);  
if let cell = myCollectionView .cellForItem(at: indexPath)  
{   
   // do stuff...  
}  

Upvotes: 19

dy_
dy_

Reputation: 2491

In Swift 2 you can get the row with:

let point : CGPoint = sender.convertPoint(CGPointZero, toView:myTableView)
let indexPath = myTableView.indexPathForRowAtPoint(point)
let cell = myTableView.cellForRowAtIndexPath(indexPath!)

Upvotes: -1

SameerVerma
SameerVerma

Reputation: 13

try cell.selected and then change the color

Upvotes: 0

Related Questions