ios - 如何处理 UICollectionviewCell 或 UITableViewCell 内的按钮触摸

标签 ios swift uitableview uicollectionview uicollectionviewcell

这是我在创建cell时一直陷入困境的一个问题。

假设我有一个自定义单元格 (PlaceCell),我在不同的 Controller 和 Collection View 中使用它。它有一个标签,用于标识地点名称 (PlaceNameLabel),并且当用户点击它时将导航到地点详细信息。

这与 Controller 、 Collection View 或单元格的使用位置无关,这与其使用位置无关。

所以我必须将 PlaceNameLabel 的 UITapGestureRecognizer 代码放入 PlaceCell 类中。

class PlaceCell: UICollectionViewCell {
     @IBOutlet weak var placeName: UILabel!
     override func awakeFromNib() {
        super.awakeFromNib()
        initEventListeners()
    }

    func initEventListeners() {
        let tapGestureRecognizer = UITapGestureRecognizer(target: self, 
                   action: #selector(handlePlaceNameTouch))
    }

    func handlePlaceNameTouch() {
        // I have to push a new view controller here
    }
}

但是如果我想推送地点详细 View Controller ,我需要访问该 Controller 。如果我想访问 Controller ,我有两个选择,这就是我陷入困境的地方,我读过很多SO问题的答案,其中大多数建议选择第二个选项,但我认为第一个是更好的方法。但不知道引用cell内的 Controller 是否有问题。

您能否分享一下您的意见或任何其他方法来处理这个问题?

第一个选项

引用单元内的 Controller ,

extension MyController: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PlaceCell", for: indexPath) as! PlaceCell
        cell.controller = self
        return cell
    }
}

class PlaceCell: UICollectionViewCell {
     var controller: UIViewController?
     @IBOutlet weak var placeName: UILabel!
     override func awakeFromNib() {
        super.awakeFromNib()
        initEventListeners()
    }

    func initEventListeners() {
        let tapGestureRecognizer = UITapGestureRecognizer(target: self, 
                   action: #selector(handlePlaceNameTouch))
    }

    func handlePlaceNameTouch() {
        controller.navigationController.pushViewController(PlaceDetailController(), 
                                             animated: true)
    }
}

第二个选项

创建协议(protocol)和委托(delegate),将事件传递给 Controller ​​并做任何你想做的事情, (我认为这不好,因为操作是关于单元的,并且我必须多次创建协议(protocol)函数,因为我在不同的 Controller 中使用这个单元)

protocol PlaceCellDelegate {
  func handlePlaceNameTouch()
}

class PlaceCell: UICollectionViewCell {
    var delegate: PlaceCellDelegate?
    @IBOutlet weak var placeName: UILabel!
    override func awakeFromNib() {
        super.awakeFromNib()
        initEventListeners()
    }

    func initEventListeners() {
        let tapGestureRecognizer = UITapGestureRecognizer(target: self, 
                           action: #selector(handlePlaceNameTouch))
    }

    func handlePlaceNameTouch() {
        delegate?.handlePlaceNameTouch()
    }
}

extension MyController: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, PlaceCellDelegate {
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PlaceCell", for: indexPath) as! PlaceCell
        cell.delegate = self
        return cell
    }

    func handlePlaceNameTouch() {
          self.navigationController.pushViewController(PlaceDetailController(), animated: true)
    }
}

最佳答案

您无需专门处理单元格选择。无需使用 UITapGestureRecognizer 或无需实现您自己的协议(protocol)来检测单元格选择。

UICollectionViewUITableView 有自己的协议(protocol)。

UICollectionView 的单元格选择委托(delegate) - UICollectionViewDelegate 协议(protocol)

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)

UITableView 的单元格选择委托(delegate) - UITableViewDelegate 协议(protocol)

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)

确认协议(protocol)并在UIViewController上设置委托(delegate)

class viewcontroller : UICollectionViewDelegate {
   @IBOutlet weak collectionView: UICollectionView!

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

并在 View Controller 内实现协议(protocol)方法,正如我上面提到的。

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
   //indexPath - Index path of selected cell.

   // Add you cell selection logic here. 
}

当您点击单元格时,将触发此方法。在此方法内,从数据源数组中获取模型。并根据用户选择的单元格(模型)导航到详细 View 。

关于ios - 如何处理 UICollectionviewCell 或 UITableViewCell 内的按钮触摸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45062590/

相关文章:

ios - 多个应用程序对于自定义 URL 应用程序具有相同的 URL 标识符

ios - 数组在错误的位置返回值

swift - PageViewController 不适用于 Swift 2.0

ios - Swift,无法用更多行更新 TableView

swift、numberOfRowsInSection 和 cellForRowAt 函数不返回值

ios - UIImageView 在 UITableViewCell 内旋转动画

iOS:如何围绕中心点旋转 UIImageView?

ios - 如何在 UITableViewCell 中获取屏幕宽度?

ios - UITableViewController 不显示任何数据

iphone - 分配 - 添加为附件 View - 发布 : does it leak?