如何检测 UICollectionViewCell 中的 UITableViewCell 中的按钮点击?

Posted

技术标签:

【中文标题】如何检测 UICollectionViewCell 中的 UITableViewCell 中的按钮点击?【英文标题】:How to detect button tap in a UITableViewCell which is in a UICollectionViewCell? 【发布时间】: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 或者您可以创建委托模式或使用闭包来通知控制器。 【参考方案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

【讨论】:

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

以上是关于如何检测 UICollectionViewCell 中的 UITableViewCell 中的按钮点击?的主要内容,如果未能解决你的问题,请参考以下文章

检测是不是正在显示 UICollectionViewCell

检测位于另一个 uicollectionview 内的 uicollectionView 的哪个 UICollectionViewCell 位于中心

如何将 UICollectionViewCell 的可触摸区域扩展到其边界之外?

当动画为假时,如何检测UIScrollView已完成滚动?

检测 iOS UICollectionCell 何时离开屏幕

UICollectionViewCell 和自动布局缩放