Why custom button in CollectionView load only into last cell? (Swift)

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



Why custom button in CollectionView load only into last cell? (Swift)



Why my custom button in CollectionView load only into last cell?



How can i make that button load in all cells?


var editButton = UIButton()

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCellCard

switch ColorSegment.selectedSegmentIndex
case 0:
cell.CardView.backgroundColor = ColorArray[indexPath.row]
cell.ColorName.text = ColorName[indexPath.row]
case 1:
cell.CardView.backgroundColor = CustomColorArray[indexPath.row]
cell.ColorName.text = CustomColorName[indexPath.row]

editButton.frame = CGRect(x:63, y:0, width:20,height:20)
editButton.layer.cornerRadius = 10
editButton.backgroundColor = UIColor.lightGray
editButton.layer.setValue(indexPath.item, forKey: "index")
editButton.setImage(UIImage(named: "CloseScan"), for: UIControlState.normal)
editButton.addTarget(self, action: #selector(deleteCell), for: UIControlEvents.touchUpInside)
cell.addSubview(editButton)
default: print("error with switch statement for cell data")

return cell





Edit Button Function


if EditButton.currentTitle == "Edit"
EditButton.setTitle("Cancel", for: .normal)
//DeleteButton.isHidden = false
else if EditButton.currentTitle == "Cancel"
EditButton.setTitle("Edit", for: .normal)
//DeleteButton.isHidden = true





Don't create a instance variable for the button, it must be a local variable in - case 1
– vivekDas
Aug 6 at 6:34




3 Answers
3



The problem is you are adding same editButton in all the cell, you need to create new UIButton for all the cell.


editButton


UIButton



So change line


editButton.frame = CGRect(x:63, y:0, width:20,height:20)



With


//Create new button instance every time
let editButton = UIButton(frame: CGRect(x:63, y:0, width:20,height:20))



Also cellForItemAt will reuse the cell so instead of creating new UIButton each time you can try like this.


cellForItemAt


UIButton


let editButton: UIButton
if let btn = cell.viewWithTag(101) as? UIButton
editButton = btn

else
editButton = UIButton(frame: CGRect(x:63, y:0, width:20,height:20))

editButton.layer.cornerRadius = 10
editButton.backgroundColor = UIColor.lightGray
editButton.layer.setValue(indexPath.item, forKey: "index")
editButton.setImage(UIImage(named: "CloseScan"), for: UIControlState.normal)
editButton.addTarget(self, action: #selector(deleteCell), for: UIControlEvents.touchUpInside)
//Set tag for reuse
editButton.tag = 101
cell.addSubview(editButton)



You can get indexPath of cell in button action like this.


@objc func deleteCell(_ sender: UIButton)
let point = sender.superview?.convert(sender.center, to: self.collectionView) ?? .zero
guard let indexPath = self.collectionView.indexPathForItem(at: point) else return
//Use indexPath here



Edit: If you want to hide or show the button than its better that you just add button in your design and create one outlet of in your CustomCollectionViewCell after that in cellForItemAt just hide and show button on basis of condition. From your code you need to show the delete button if selected index of segment is 1. So make your cellForItem like this.


cellForItemAt


cellForItem


func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCellCard

cell.CardView.backgroundColor = ColorArray[indexPath.row]
cell.ColorName.text = ColorName[indexPath.row]
//Add delete button in the xib or storyboard collectionViewCell
//Now hide this button if EditButton title is not "Edit"
cell.editButton.isHidden = EditButton.currentTitle != "Edit"
//Add action of button
cell.editButton.addTarget(self, action: #selector(deleteCell), for: UIControlEvents.touchUpInside)
return cell



After that in your edit button action reload the collectionView after you set the button title.


if EditButton.currentTitle == "Edit"
EditButton.setTitle("Cancel", for: .normal)
else if EditButton.currentTitle == "Cancel"
EditButton.setTitle("Edit", for: .normal)

//Reload your collectionView
self.collectionView.reloadData()





But how can i work with this button in ViewDidLoad?
– B2Fq
Aug 6 at 6:30





what you want to do in ViewDidLoad with the button ?
– vivekDas
Aug 6 at 6:34





@NiravD Thanks but i already have a function to delete
– B2Fq
Aug 6 at 6:40





@NiravD Could you help how to hide the button using the tag?
– B2Fq
Aug 6 at 6:40






@B2Fq I'm not getting your question to show delete button in all cell you have to create new button object in cellForItem also in which cell you want to hide the cell ? Edit your question with more detail
– Nirav D
Aug 6 at 6:42




I think you could move the line:


var editButton = UIButton()



To func cellForItemAt :


func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCellCard

switch ColorSegment.selectedSegmentIndex
case 0:
cell.CardView.backgroundColor = ColorArray[indexPath.row]
cell.ColorName.text = ColorName[indexPath.row]
case 1:
cell.CardView.backgroundColor = CustomColorArray[indexPath.row]
cell.ColorName.text = CustomColorName[indexPath.row]

// create editButton in here
var editButton = UIButton()

editButton.frame = CGRect(x:63, y:0, width:20,height:20)
editButton.layer.cornerRadius = 10
editButton.backgroundColor = UIColor.lightGray
editButton.layer.setValue(indexPath.item, forKey: "index")
editButton.setImage(UIImage(named: "CloseScan"), for: UIControlState.normal)
editButton.addTarget(self, action: #selector(deleteCell), for: UIControlEvents.touchUpInside)
cell.addSubview(editButton)

default: print("error with switch statement for cell data")

return cell



move your button logic outside of switch statement like this


func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCellCard

switch ColorSegment.selectedSegmentIndex
case 0:
cell.CardView.backgroundColor = ColorArray[indexPath.row]
cell.ColorName.text = ColorName[indexPath.row]
case 1:
cell.CardView.backgroundColor = CustomColorArray[indexPath.row]
cell.ColorName.text = CustomColorName[indexPath.row]

default: print("error with switch statement for cell data")

var editButton = UIButton.init(frame: CGRect.init(x: 63, y: 0, width: 20, height: 20))
editButton.layer.cornerRadius = 10
editButton.backgroundColor = UIColor.lightGray
editButton.layer.setValue(indexPath.item, forKey: "index")
editButton.setImage(UIImage(named: "CloseScan"), for: UIControlState.normal)
editButton.addTarget(self, action: #selector(deleteCell), for: UIControlEvents.touchUpInside)
cell.addSubview(editButton)
return cell








By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard