做的最好的事情就是讓自定義協議爲自定義單元格類
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
中的每個單元格:
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*/)
}
}
嗯,這可能也會起作用。我沒有想過以這種方式使用閉包。 – Extragorey
閉包實際上比委託模式更簡單易用。 – PGDev