Swift 将按钮添加到打开新控制器的 UICollectionViewCell

Swift add button to UICollectionViewCell that opens new controller

我在 UICollectionViewController 上有一个 UICollectionViewCell header,我在上面添加了一个按钮。我希望按钮在单击时将新的视图控制器推到当前视图控制器之上。问题是按钮无法访问 UICollectionViewController 的导航控制器,所以我无法直接将控制器从连接器推送到按钮(据我所知)。有什么办法可以做到这一点?也许可以重写某些内容,例如 collectionView 函数。谢谢!

如果您只想处理单元格选择,UICollectionViewDelegate 中有一个 handy method,您可以实现它以获取按下的单元格的索引路径。

如果您的目标是在单元格(或什至多个)内有一个自定义按钮,您可以使用委托模式将用户操作检索到您的控制器,然后以任何方式处理,包括 pushing/presenting 新控制器.将控制器的实例(管理集合视图的实例)分配给单元格的委托成员。

  1. 定义一个协议,我称之为 MyCustomCellDelegate(用更适合您的情况的名称替换 MyCustomCell)。类似于 MyCustomCellDelegate: class { func didPressButtonX() }
  2. 在您的单元格 subclass 中声明一个可选委托 属性。 weak var delegate: MyCustomCellDelegate?
  3. 通过 class 您想要响应按钮按下(或您的协议定义的任何其他交互)来实现您的委托协议。
  4. 每次您 create/dequeue 为您的 UICollectionView 使用一个单元格时,您将委托 属性 设置为管理集合视图的视图控制器。 cell.delegate = self(如果在视图控制器内部完成)。
  5. 在您的自定义单元格中收到 UI 事件后,使用您的委托 属性 将操作检索到控制器(或使用您在分配 属性 时使用的任何对象)。类似于:delegate?.didPressButtonX()
  6. 在实现 MyCustomCellDelegate 的 class 中使用推送新控制器的方法。

下面我将提供示例代码,其中应提供有关所提议解决方案的实施的更多详细信息:

// In your UICollectionViewCell subclass file

protocol MyCustomCellDelegate: class {
    func didPressButtonX()
    func didPressButtonY()
}

MyCustomCell: UICollectionViewCell {
    weak var delegate: MyCustomCellDelegate?

    @IBOutlet var buttonX: UIButton!
    @IBOutlet var buttonY: UIButton!

    @IBAction func didPressButtonX(sender: Any) {
        delegate?.didPressButtonX()
    }

    @IBAction func didPressButtonY(sender: Any) {
        delegate?.didPressButtonY()
    }
}

// Now in your UICollectionViewController subclass file

MyCustomCollectionViewController: UICollectionViewController {
    // ...

    override func collectionView(UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier identifier: "YourCellIdentifierGoesHere", for indexPath: indexPath) as! MyCustomCell
        // In here we assign the delegate member of the cell to make sure once
        // an UI event occurs the cell will call methods implemented by our controller
        cell.delegate = self

        // further cell setup if needed ...

        return cell
    }
}

// In order for the instance of our controller to be used as cell's delegate 
// we implement the protocol that we defined earlier in the cell file 
extension MyCustomCollectionViewController: MyCustomCellDelegate {
    func didPressButtonX() {
        print("X button was pressed")

        // now lets finally push some new controller
        let yourNextCoolViewController = UIViewController()
        self.push(yourNextCoolViewController, animated: true)

        // OR if you are using segues
        self.performSegue(withIdentifier: "YourSegueIdentifierGoesHere", sender: self)
    }

    func didPressButtonY() {
        print("Y button was pressed")
    }
}