【问题标题】:How to detect button tap in a UITableViewCell which is in a UICollectionViewCell?如何检测 UICollectionViewCell 中的 UITableViewCell 中的按钮点击?
【发布时间】:2019-01-14 08:04:51
【问题描述】:

我正在尝试检测UITableViewCell 中的按钮点击,该UICollectionViewCell 中的按钮。

UICollectionView 的委托和数据源是我的ViewController。每个UICollectionViewCell 中都有一个UITableView。而UITableViewCell 的委托和数据源是UICollectionViewCell

我需要检测ViewController 中的按钮点击。

视图控制器

@IBOutlet collectionView: UICollectionView!

override func viewDidLoad() {
    super.viewDidLoad()
    collectionView.delegate = self
    collectionView.dataSource = self
}

UICollectionView

@IBOutlet tableView: UITableView!

override func awakeFromNib() {
    super.awakeFromNib()
    tableView.delegate = self
    tableView.dataSource = self
}

UITableViewCell

@IBAction func buttonTapped(_ sender: CustomButton) {
    // Detect Button Tap in ViewController
}

【问题讨论】:

  • 添加一些额外的代码
  • 在集合视图单元格类中调用 tableView 的委托和数据源方法
  • 好吧,如果它是单元格中唯一的按钮,您可以依赖表格视图委托 didSelect 或者您可以创建委托模式或使用闭包来通知控制器。

标签: ios swift uitableview uicollectionview


【解决方案1】:

我建议你使用委托模式。


所以您需要一种用于表格视图单元格的协议和一种用于集合视图单元格的协议

protocol TableCellDelegate: class {
     func buttonPressed(_ sender: CustomButton)
}

protocol CollectionCellDelegate: class {
     func buttonInTableCellPressed(_ sender: CustomButton)
}

现在为单元格子类创建delegate 变量

class TableCell: ... {
    weak var delegate: TableCellDelegate?
}

class CollectionCell: ... {
    weak var delegate: CollectionCellDelegate?
}

继续实现TableCellDelegateCollectionView 并在表格单元格委托的方法中调用单元格委托的方法

extension CollectionCell: TableCellDelegate {
    func buttonPressed(_ sender: CustomButton) {
        delegate?.buttonInTableCellPressed(sender)
    }
}

接下来将CollectionCellDelegate 实现到您的视图控制器

extension ViewController: CollectionCellDelegate {
    func buttonInTableCellPressed(_ sender: CustomButton) {
        ... // this is called when button in table view cell is pressed
    }
}

现在,不要忘记在ViewController 中设置cellForItemAt 内的集合单元代表和CollectionCellcellForRowAt 内的表格单元的代表

class ViewController: UICollectionViewDelegate, UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        ...
        cell.delegate = self
        ...
    }
}

class CollectionCell: UICollectionViewCell, UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        ...
        cell.delegate = self
        ...
    }
}

现在,最后,当按下按钮时,在表格单元格内调用委托方法

@IBAction func buttonTapped(_ sender: CustomButton) {
    delegate?.buttonPressed(sender)
}

【讨论】:

  • 我会将单元格传递给委托方法,而不是按钮。这样,委托就可以轻松确定与按钮对应的适当数据模型项。
  • @Paulw11 来自他的问题并不清楚他需要什么按钮。无论如何,如果他需要传递适当的数据模型项,他可以只传递该项而不是按钮,对吗?
  • 嘿,@RobertDresler,感谢您的回答!看起来这也是一个正确的答案,但我接受了另一个答案,因为它是第一个答案,也解决了我的问题。祝你有美好的一天!
  • @Sercan 但是,他的答案不正确,他没有告诉您您需要设置集合视图单元格的委托,因此他的答案不是第一个正确答案;)
  • @RobertDresler 就我个人而言,我不会将视图(如单元格)直接绑定到模型对象。
【解决方案2】:

您可以为此编写自己的委托。

protocol ButtonDelegate: class {
    func buttonTapped(_ button: UIButton)
}

然后,在你的ViewController 中实现它,并在点击按钮时做任何你想做的事情。

在您的UICollectionView 和您的UITableViewCell 中,添加一个属性:

weak var buttonDelegate: ButtonDelegate?

然后,修改你的UITableViewCell

@IBAction func buttonTapped(_ sender: CustomButton) {
    buttonDelegate?.buttonTapped(sender)
}

ViewController 中,您必须在UICollectionView 上设置委托:

collectionView.buttonDelegate = self

最后,在UICollectionViewcellForRowAt 方法中,将UITableViewCellbuttonDelegate 属性设置为UICollectionViewbuttonDelegate,即您的ViewController

cell.buttonDelegate = buttonDelegate

【讨论】:

  • 我会将单元格传递给委托方法,而不是按钮。这样,委托就可以轻松确定与按钮对应的适当数据模型项。
  • 如果您不设置集合视图单元格的委托,这将如何工作?
  • 嘿@fabianbraach,谢谢你的回答!我希望找到一种直接的方法来检测来自视图控制器的单元格中的点击,但我想这就是它的工作原理。这就像将委托(?)移动到上层阶级,对吧?在这种情况下我应该总是这样做吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-17
相关资源
最近更新 更多