简体   繁体   English

发出出列UICollectionViewCell的问题

[英]Issue dequeuing UICollectionViewCell

I have a UICollectionView which I fill up with a NSFetchedResultsControllerDelegate. 我有一个UICollectionView,我用NSFetchedResultsControllerDelegate填充。 Data arrives sporadically. 数据偶尔到来。 I have implemented a method for inserting/updating/deleting/etc. 我已经实现了插入/更新/删除/等的方法。 items in the collectionView with the FetchedResultsController delegate callbacks. 具有FetchedResultsController委托回调的collectionView中的项目。 So that's the context. 这就是上下文。 My problem is that my custom UICollectionViewCell has a UIButton in it, with a specific action and target. 我的问题是我的自定义UICollectionViewCell中有一个UIButton,具有特定的动作和目标。 So when the collectionview is dequeueing cells, I noticed that several cells had the same UIButton reference. 因此,当collectionview使单元格出列时,我注意到有几个单元格具有相同的UIButton引用。 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. 例如,当我点击一个按钮时,它就像我点击3个不同单元格的按钮一样。 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 . 您仍然希望使用可重复使用的按钮创建可重用的单元格,但是当您在cellForRowAtIndexPath中将单元格出列时,将该按钮的(或任何UIViewtag属性设置为单元格的indexPath

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. 注意: UIViewtag属性是一个Int ,所以如果你需要整个索引路径,这在使用获取结果控制器时非常有用,你可以子类化UIButton并为它提供一个属性,你可以存储索引路径,以相同的方式设置和检索它。

I'm guessing you set the button's target and action in -collectionView:cellForItemAtIndexPath: . 我猜你在-collectionView:cellForItemAtIndexPath:设置了按钮的目标和动作-collectionView:cellForItemAtIndexPath: . In your custom cell, you could override -prepareForReuse and remove all targets and actions from your button. 在自定义单元格中,您可以覆盖-prepareForReuse并从按钮中删除所有目标和操作。

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 在单元格上调用Action方法
  3. Cell informs its delegate that it should do something Cell告知其代表它应该做些什么

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. 它还有一个额外的好处,就是让你将你的UIButton私有保存到单元格,所以,如果你想要将该按钮更改为将来使用手势识别器的视图,你可以只更新单元格的实现并保持它的界面不变。

In the second approach, it is still good practice to set the cell's delegate to nil in -prepareForReuse . 在第二种方法中,将单元格的委托设置为-prepareForReuse nil仍然是一种好习惯。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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