从UICollectionViewCell按钮执行Segue,与Cell Click不同

Mag*_*ios 3 ios uicollectionviewcell swift swift3

我有一个UICollectionViewCell,有一个UIButton.我有两种不同的行为.第一个,当用户按下单元格时,它将切换到另一个视图didSelectITemAt; 第二个,当用户按下UIButton单元格内部时.
我的问题是,在Swift Code上MyCollectionViewCell,我不能执行一个segue,当我编写代码时:

self.performSegue(withIdentifier: "toStoreFromMyDiscounts", sender: nil)
Run Code Online (Sandbox Code Playgroud)

它说错误:

类型MyCollectionViewCell的值没有成员performSegue.

我也写不出来prepareForSegue,也不自动完成.

如何从单元格创建segue,这与单击单元格本身不同?

dir*_*nee 10

你不能调用performSegue从您的UICollectionViewCell子类,因为没有声明的接口 上UICollectionViewCell那样.

它工作的原因didSelectItemAtIndexPath()是因为我认为你的委托UICollectionView是一个UIViewController子类,有什么函数叫做performSegueWithIdentifier :()`.

您需要在您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)
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑: 如果您关心,触摸事件发生在哪个单元格中,请使用委托模式.

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)
    }
}
Run Code Online (Sandbox Code Playgroud)