简体   繁体   中英

Issue dequeuing UICollectionViewCell

I have a UICollectionView which I fill up with a NSFetchedResultsControllerDelegate. Data arrives sporadically. I have implemented a method for inserting/updating/deleting/etc. items in the collectionView with the FetchedResultsController delegate callbacks. So that's the context. My problem is that my custom UICollectionViewCell has a UIButton in it, with a specific action and target. So when the collectionview is dequeueing cells, I noticed that several cells had the same UIButton reference. That's not cool. For example, when I tap on a button, it acts as if i tap on the button of 3 different cells. Because of the dequeueing system, these cells are actually the same cell (meaning they have the same memory reference). Is there a system where I could have a unique reference for each of my cells. What I am asking is how can I bypass the dequeueing system?

What you want to do is tag each button with the index path of its cell, not "bypass the dequeueing system". You still want to create reusable cells with reusable buttons, but set that button's (or any UIView ) tag property to be the indexPath of the cell when you are dequeuing the cell in cellForRowAtIndexPath .

cell.someButton.tag = indexPath.row

and then when you call a function with that button as a sender you access the tag:

@IBAction func someButtonPressed(sender: UIButton) {
    let index = sender.tag
    // Do something unique to that cell with that tag
}

Note: UIView 's tag property is an Int , so if you need the entire index path, which is very useful when using a fetched results controller, you can subclass UIButton and give it a property where you can store the index path, and just set and retrieve it the same way.

I'm guessing you set the button's target and action in -collectionView:cellForItemAtIndexPath: . In your custom cell, you could override -prepareForReuse and remove all targets and actions from your button.

Alternatively, an approach I have used is to make the custom cell the button target and to expose this action to your data source using a delegate call back, so:

  1. Button pressed
  2. Action method is called on cell
  3. Cell informs its delegate that it should do something

This solves your problem in that the cell has a single delegate, rather then the multiple target-actions that you're seeing. It also has the added advantage of letting you keep your UIButton private to the cell so, if you, say, wanted to change that button to a view with a gesture recogniser in the future, you could update the implementation of the cell only and keep its interface unchanged.

In the second approach, it is still good practice to set the cell's delegate to nil in -prepareForReuse .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM