我在 CollectionViewCell 内有一个 UIButton,它又在 TableViewCell 内。如何通过单击 UIButton 导航到下一个视图控制器?

Posted

技术标签:

【中文标题】我在 CollectionViewCell 内有一个 UIButton,它又在 TableViewCell 内。如何通过单击 UIButton 导航到下一个视图控制器?【英文标题】:I have a UIButton inside a CollectionViewCell which is again inside the TableViewCell.How do i navigate to next view contoller by clicking UIButton? 【发布时间】:2019-01-21 05:42:05 【问题描述】:

我在UICollectionViewCell 里面有UIButton,它在UITableViewCell 里面,我需要在点击UIButton 时导航另一个UIViewController。但是UINavigationControllerUICollectionViewCell 中不起作用。有人可以帮忙吗?

我的代码中没有找到任何导航控制器。

import UIKit

class TrendingProductTVCell: UITableViewCell 

    @IBOutlet weak var trendingProductCV: UICollectionView!

    override func awakeFromNib() 
        super.awakeFromNib()
        trendingProductCV.delegate = self
        trendingProductCV.dataSource = self
    



extension TrendingProductTVCell: UICollectionViewDataSource, UICollectionViewDelegate 

    func numberOfSections(in collectionView: UICollectionView) -> Int 
        return 1
    

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        let cell = trendingProductCV.dequeueReusableCell(withReuseIdentifier: "TrendingProductsCVCell", for: indexPath) as? TrendingProductsCVCell
        cell?.trendingAddToCartBtn.addTarget(self, action: #selector(addToCartBtnTapped), for: .touchUpInside)
        return cell!
    

    @objc
    func addToCartBtnTapped(sender: UIButton)
       let productDetail = trendingProductsDataArray[sender.tag]
    

【问题讨论】:

你可以在storyboard中添加导航控制器,然后你可以参考self.navigationcontroller push。此外,您应该在视图控制器类上扩展数据源方法。 【参考方案1】:

您可以使用委托协议。

protocol TrendingProductTVCellDelegate 
    func addToCart(product: Product)


class TrendingProductTVCell: UITableViewCell 
    var delegate: TrendingProductTVCellDelegate?


extension TrendingProductTVCell: UICollectionViewDataSource, UICollectionViewDelegate 
    @objc func addToCartBtnTapped(sender: UIButton)
       let productDetail = trendingProductsDataArray[sender.tag]
       delegate?.addToCart(product: productDetail)
    

UINavigationController 只能通过 ViewController 访问。所以你的 TrendingProductViewController 必须监听协议,然后你现在可以访问 navigationController。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = ... // your TrendingProductTVCell
    cell.delegate = self // <- important
    ...


extension TrendingProductViewController: TrendingProductTVCellDelegate 
    func addToCart(product: Product) 
        navigationController.push() // your rest code here....
    

【讨论】:

【参考方案2】:

你可以做这两件事中的任何一件 1. 使用 NotificationCenter 发布通知,发送您的 userInfo 中的 productDetail 并监听包含您的 tableViewViewController 中的通知 2. 或者,您可以简单地创建一个 Protocol,使用您希望在选择产品时触发的方法,在 TableViewCell 中添加 delegate 属性strong>,在创建单元格时发送控制器的引用(在 cellForRowAt: 中),并在选择产品时调用该 delegate 上的方法。 虽然我更喜欢使用第二种方法,但在这两种方法中您都可以处理新视图控制器的推送。

【讨论】:

【参考方案3】:

使用委托:通过委托,您可以向调用者提供更多信息,并且在这种情况下更加灵活。最佳解决方案使用委托。

【讨论】:

【参考方案4】:

您可以使用此扩展为任何视图获取 parentViewController:

extension UIView 
  var parentViewController: UIViewController? 
    var parentResponder: UIResponder? = self
    while parentResponder != nil 
        parentResponder = parentResponder!.nextResponder()
        if parentResponder is UIViewController 
            return parentResponder as! UIViewController!
        
    
    return nil
  

然后您将能够访问 UITableViewCellUICollectionViewCell 内的 parentViewController。获取此 parentViewController 的 navController 并从 UICollectionViewCell 内部推送到下一个。

【讨论】:

以上是关于我在 CollectionViewCell 内有一个 UIButton,它又在 TableViewCell 内。如何通过单击 UIButton 导航到下一个视图控制器?的主要内容,如果未能解决你的问题,请参考以下文章

访问 CollectionViewCell

UITextView 避免 collectionViewCell 被点击

为啥不去 CollectionViewCell?

从 collectionViewCell 中的 tableView 重新加载数据

单击 CollectionViewCell 内的 ImageView 以转到 ViewController

删除项目后为 CollectionViewCell 设置动画