UICollectionViewCell内按钮的可用性?

问题描述

我有一个ProductVC.swift(ProductViewController)文件一个ProductCell.swift。 ProductVC包含一个UICollectinView,ProductCell是一个特定的UICollectionViewCell。

ProductCell.xib 看起来像这样:

enter image description here

ProductVC包含一个包含所有单元格数据(产品)的数组,并填充单元格。

我的目标用户应该有可能喜欢某种产品。他可以通过单击每个单元格右上角的“赞”按钮来做到这一点。每个单元格都显示由productID指定的特定产品。

我的问题:“赞”按钮动作(IBAction func)位于ProductCell中。 ProductCell没有单元格数据。单元格数据以阵列形式存储在ProductVC中。所以我不知道该如何捕捉用户想要的产品(产品ID)。

我的尝试:使用下面的代码,我可以获取用户单击“赞”按钮的单元格的indexPath。但是我无法使用此indexPath来获取产品数据,因为数据存储在ProductVC中。我也可以将数据存储在ProductCell中,但这不是一种干净的方法。 mb是否可以将此indexPath提供给ProductVC?

extension UICollectionView {
    func indexPathForView(_ view: UIView) -> IndexPath? {
        let center = view.center
        let viewCenter = self.convert(center,from: view.superview)
        let indexPath = self.indexPathForItem(at: viewCenter)
        return indexPath
    } 
}

let superview = self.superview as! UICollectionView
    
if let indexPath = superview.indexPathForView(button) {
    print(indexPath) // indexPath of the cell where the button was pressed
}

解决解决方案是回调闭包:

//UICollectionViewCell
var saveProductLike: ((_ index: Int) -> Void)?
@IBAction func likedButtonClicked(_ sender: UIButton) {
    print("Liked button clicked!")
    let productArrayIndex = calculateProductArrayIndex(for: sender)
    saveProductLike?(productArrayIndex!)
}

//UIViewController
cell.saveProductLike = { (index) -> Void in
    print(index)  
}

解决方法

有几种方法可以解决此问题,但我将讨论最常见的一种使用委托的方法。

protocol ProductCellDelegate: AnyObject {
  func productCellDidPressLikeButton(_ cell: ProductCell)
} 

ProductCell中定义属性weak var delegate: ProductCellDelegate?,然后在“喜欢”按钮的目标操作中通知您的代表

@objc private likeButtonPressed(_ sender: Any) {
  delegate?.productCellDidPressLikeButton(self)
}

在您的视图控制器中,您可以遵循协议并像这样实现它:

func productCellDidPressLikeButton(_ cell: ProductCell) {
  guard let ip = collectionView.indexPath(for: cell) else { return }
  // process event,get product via index...
}

然后,您需要将视图控制器设置为collectionView(_:willDisplay:forItemAt:)中的委托或 collectionView(_:cellForItemAt:)cell.delegate = self