我有UICollectionViewCell
,UIButton
。我有两种不同的行为。第一个,当用户按下单元格时,它将转到didSelectITemAt
的另一个视图;第二个,当用户按下单元格内的UIButton
时
我的问题是,在MyCollectionViewCell
的Swift代码中,当我编写代码时,我无法执行segue:
self.performSegue(withIdentifier: "toStoreFromMyDiscounts", sender: nil)
它说错误:
MyCollectionViewCell类型的值没有成员performSegue。
我也写不出prepareForSegue
,它不会自动完成。
如何从单元格创建segue,这与单击单元格本身不同?
答案 0 :(得分:10)
您无法从performSegue
子类中致电UICollectionViewCell
,因为UICollectionViewCell
上的no interface declared就是这样。
它工作didSelectItemAtIndexPath()
的原因是因为我认为UICollectionView
的{{3}}是UIViewController
子类,具有名为delegate的函数
您需要在UIViewController
中点击按钮时通知您的UICollectionViewCell
,以获得各种可能性,例如KVO或使用代表。
这是一个小代码片段,如何使用KVO。这个解决方案很棒,只要你不在乎,按下按钮的是哪个单元格。
import UIKit
class CollectionViewCell: UICollectionViewCell {
@IBOutlet weak var button: UIButton!
}
class CollectionViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
}
extension CollectionViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell: CollectionViewCell = self.collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionViewCell
// Add your `UIViewController` subclass, `CollectionViewController`, as the target of the button
// Check out the documentation of addTarget(:) https://developer.apple.com/reference/uikit/uicontrol/1618259-addtarget
cell.button.addTarget(self, action: #selector(buttonTappedInCollectionViewCell), for: .touchUpInside)
return cell
}
func buttonTappedInCollectionViewCell(sender: UIButton) {
self.performSegue(withIdentifier: "toStoreFromMyDiscounts", sender: nil)
}
}
修改强> 如果您关心触摸事件发生在哪个单元格中,请使用委托模式。
import UIKit
protocol CollectionViewCellDelegate: class {
// Declare a delegate function holding a reference to `UICollectionViewCell` instance
func collectionViewCell(_ cell: UICollectionViewCell, buttonTapped: UIButton)
}
class CollectionViewCell: UICollectionViewCell {
@IBOutlet weak var button: UIButton!
// Add a delegate property to your UICollectionViewCell subclass
weak var delegate: CollectionViewCellDelegate?
@IBAction func buttonTapped(sender: UIButton) {
// Add the resposibility of detecting the button touch to the cell, and call the delegate when it is tapped adding `self` as the `UICollectionViewCell`
self.delegate?.collectionViewCell(self, buttonTapped: button)
}
}
class CollectionViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
}
extension CollectionViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell: CollectionViewCell = self.collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionViewCell
// Asssign the delegate to the viewController
cell.delegate = self
return cell
}
}
// Make `CollectionViewController` confrom to the delegate
extension CollectionViewController: CollectionViewCellDelegate {
func collectionViewCell(_ cell: UICollectionViewCell, buttonTapped: UIButton) {
// You have the cell where the touch event happend, you can get the indexPath like the below
let indexPath = self.collectionView.indexPath(for: cell)
// Call `performSegue`
self.performSegue(withIdentifier: "toStoreFromMyDiscounts", sender: nil)
}
}
答案 1 :(得分:0)
另一种解决方案也像魅力一样:
extension YOURViewController : UICollectionViewDataSource
{
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "YOURCell", for: indexPath) as! YOURCollectionViewCell
cell.butTapped = {
[weak self] (YOURCollectionViewCell) -> Void in
// do your actions when button tapped
}
}
return cell
}
class YOURCollectionViewCell: UICollectionViewCell
{
var butQRTapped: ((YOURCollectionViewCell) -> Void)?
@IBAction func deleteButtonTapped(_ sender: AnyObject) {
butTapped?(self)
}
}
答案 2 :(得分:0)
这是一个优雅的解决方案,只需要几行代码:
快速4 + 代码
class MyCustomCell: UICollectionViewCell {
static let reuseIdentifier = "MyCustomCell"
@IBAction func onAddToCartPressed(_ sender: Any) {
addButtonTapAction?()
}
var addButtonTapAction : (()->())?
}
下一步,在
的闭包内部实现要执行的逻辑override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MyCustomCell.reuseIdentifier, for: indexPath) as? MyCustomCell else {
fatalError("Unexpected Index Path")
}
// Configure the cell
// ...
cell.addButtonTapAction = {
// implement your logic here, e.g. call preformSegue()
self.performSegue(withIdentifier: "your segue", sender: self)
}
return cell
}
您也可以将这种方法用于表视图控制器。