从UICollectionViewCell传播自定义事件

我有一个自定义的UICollectionViewCell,里面有一个按钮。 当我点击按钮时,会在该子类内触发一个事件。 我想在UICollectionView本身上触发一个事件,我可以在我的视图控制器中处理它。

伪代码:

class MyCell : UICollectionViewCell { @IBAction func myButton_touchUpInside(_ sender: UIButton) { // Do stuff, then propagate an event to the UICollectionView Event.fire("cellUpdated") } } class MyViewController : UIViewController { @IBAction func collectionView_cellUpdated(_ sender: UICollectionView) { // Update stuff in the view controller // to reflect changes made in the collection view } } 

理想情况下,我定义的事件将出现在Interface Builder中的默认操作出口旁边,允许我将其拖到我的视图控制器代码中以创建上面的collectionView_cellUpdated函数,类似于@IBInspectable在公开自定义属性时的工作方式。

有没有办法在原生的Swift 3中实现这样的模式? 或者如果没有,任何可以实现的库?

我完全不理解你的问题,但是从我得到的,你可以简单地使用一个closureUIButton tap事件传递回UIViewController

例:

1.自定义UICollectionViewCell

 class MyCell: UICollectionViewCell { var tapHandler: (()->())? @IBAction func myButton_touchUpInside(_ sender: UIButton) { tapHandler?() } } 

2. MyViewController

 class MyViewController: UIViewController, UICollectionViewDataSource { //YOUR CODE.. func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! MyCell cell.tapHandler = { //Here you can do your custom handling } return cell } } 

如果您遇到任何问题,请告诉我。

最好的办法是为自定义单元类创建自定义协议

 protocol CustomCellProtocolDelegate { func custom(cell: YourCellClass, hadButton: UIButton, pressedWithInfo : [String:Any]?) } 

使此单元类具有此协议作为特殊委托,并触发此委托:

 class YourCellClass: UICollectionViewCell { var delegate : CustomCellProtocolDelegate? var indexPath : IndexPath? //Good practice here to have an indexPath parameter var yourButton = UIButton() init(frame: CGRect) { super.init(frame: frame) yourButton.addTarget(self, selector: #selector(triggerButton(sender:))) } func triggerButton(sender: UIButton) { if let d = self.delegate { d.custom(cell: self, hadButton: sender, pressedWithInfo : /*Add info if you want*/) } } } 

在您的控制器中,您将其与委托一致,并将委托应用于cellForItem: atIndexPath每个单元格cellForItem: atIndexPath

 class YourControllerThatHasTheCollectionView : UIViewController, CustomCellProtocolDelegate { func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "identifier", for: indexPath) as! YourCellClass cell.delegate = self cell.indexPath = indexPath return cell } func custom(cell: YourCellClass, hadButton: UIButton, pressedWithInfo : [String:Any]?) { //Here you can process which button was selected, etc.. and apply your changes to your collectionview } } 

最佳做法是在pressedWithInfo内的委托方法中传递单元格的indexPath参数。 它可以省去计算实际按下哪个单元格的麻烦; 因此我通常会为每个UICollectionViewCell子类添加一个indexPath元素。 更好的是,在协议方法中包含索引:

  protocol CustomCellProtocolDelegate { func custom(cell: YourCellClass, hadButton: UIButton, pressedAt: IndexPath, withInfo : [String:Any]?) } func triggerButton(sender: UIButton) { if let d = self.delegate { d.custom(cell: self, hadButton: sender, pressedAt: indexPath!, withInfo : /*Add info if you want*/) } }