当点击collectionView单元格内的按钮时,如何从tableViewCell内的collectionView获取表视图行并推送到viewController

Posted

技术标签:

【中文标题】当点击collectionView单元格内的按钮时,如何从tableViewCell内的collectionView获取表视图行并推送到viewController【英文标题】:how to get table view row and push to viewController from collectionView that's inside a tableViewCell when tapped button inside collectionView cell 【发布时间】:2020-01-16 07:59:13 【问题描述】:

我的层次结构像这样 UINavigationController->UITableviewController -> UITableViewCell -> UICollectionView-> UICollectionViewCell

我在 collectionView 单元格中有一个按钮,我设置如下:

class AccountTypeCollectionViewCell: UICollectionViewCell 
@IBOutlet weak var AccountTypeView: UIView!
@IBOutlet weak var imgAccountType: UIImageView!
@IBOutlet weak var lblAccountTypeTitle: UILabel!
@IBOutlet weak var txtAccountTypeDescription: UITextView!
@IBOutlet weak var btnMoreInfo: UIButton!
@IBOutlet weak var btnOpenNow: UIButton!
weak var delegate: CustomCollectionCellDelegate?
weak var delegate2:AccountTypeViewController?
@IBAction func btnMoreInfoPressed(_ sender: UIButton) 
    print("btnMoreInfoPressed eh dipencet")
    delegate?.OpenNows(wasPressedOnCell: self)

@IBAction func btnOpenNowPressed(_ sender: RoundButton) 
    print("btnOpenNowPressed eh dipencet")
    let accountRegular = Account(accountType: "signUp.accountTypeRegular".localized(), code: AccountType.regular)
    let signUpViewController = SignUpViewController.fromStoryboard(name: AppStoryboard.Signup.instance)
    let signUpViewModel = SignupViewModel.shared
    signUpViewModel.accountType = accountRegular
    signUpViewController.signupViewModel = signUpViewModel
    delegate2?.navigationController?.pushViewController(signUpViewController, animated: true)


class var CustomCell : AccountTypeCollectionViewCell 
    let cell = Bundle.main.loadNibNamed("AccountTypeCell", owner: self, options: nil)?.last
    return cell as! AccountTypeCollectionViewCell


override func awakeFromNib() 
    super.awakeFromNib()

在 tableView 单元格中,我这样设置:

protocol CustomCollectionCellDelegate:class 
func collectionView(collectioncell:AccountTypeCollectionViewCell?, didTappedInTableview TableCell:AccountTypeTableViewCell, collectionRow: Int)
func OpenNows(wasPressedOnCell cell: AccountTypeCollectionViewCell?)

class AccountTypeTableViewCell: UITableViewCell, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout 
    weak var cellDelegate:CustomCollectionCellDelegate?
    weak var myParent:AccountTypeViewController?
    @IBOutlet weak var collectionAccountTypeView: UIView!
    @IBOutlet weak var lblAccountTypeTitle: UILabel!
    @IBOutlet weak var collectionView: UICollectionView!
    let cellReuseId = "CollectionViewCell"
    class var customCell : AccountTypeTableViewCell 
        let cell = Bundle.main.loadNibNamed("AccountTypeTableViewCell", owner: self, options: nil)?.last
        return cell as! AccountTypeTableViewCell
    

    override func awakeFromNib() 
        super.awakeFromNib()
        let flowLayout = UICollectionViewFlowLayout()
        flowLayout.scrollDirection = .horizontal
        flowLayout.itemSize = CGSize(width: 289, height: 289)
        flowLayout.minimumLineSpacing = 10.0
        self.collectionView.collectionViewLayout = flowLayout

        self.collectionView.dataSource = self
        self.collectionView.delegate = self

        let cellNib = UINib(nibName: "AccountTypeCell", bundle: nil)
        self.collectionView.register(cellNib, forCellWithReuseIdentifier: cellReuseId)
        collectionView.reloadData()
    

    override func setSelected(_ selected: Bool, animated: Bool) 
        super.setSelected(selected, animated: animated)
    

    var collectionViewOffset: CGFloat 
        get 
            return collectionView.contentOffset.x
        

        set 
            collectionView.contentOffset.x = newValue
        
    

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 
        let cell = collectionView.cellForItem(at: indexPath) as? AccountTypeCollectionViewCell
        self.cellDelegate?.collectionView(collectioncell: cell, didTappedInTableview: self, collectionRow: indexPath.row)
    


    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return 5
    

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellReuseId, for: indexPath) as? AccountTypeCollectionViewCell
        cell?.updateCellWithImage(name: "videoCallWaiting")
        setRoundedViewWithBorder(view: (cell?.AccountTypeView)!, borderColor: "999999", bgColor: "FFFFFF")
        cell?.txtAccountTypeDescription.isScrollEnabled = true
        return cell!
    

在 AccountTypeViewController(tableview 的视图控制器)我这样设置:

extension AccountTypeViewController:CustomCollectionCellDelegate 
    func OpenNows(wasPressedOnCell cell: AccountTypeCollectionViewCell?) 
        print("hasil nya eh dipencet")
        let accountRegular = Account(accountType: "signUp.accountTypeRegular".localized(), code: AccountType.regular)
        let signUpViewController = SignUpViewController.fromStoryboard(name: AppStoryboard.Signup.instance)
        let signUpViewModel = SignupViewModel.shared
        signUpViewModel.accountType = accountRegular
        signUpViewController.signupViewModel = signUpViewModel
        navigationController?.pushViewController(signUpViewController, animated: true)
    

    func collectionView(collectioncell: AccountTypeCollectionViewCell?, didTappedInTableview TableCell: AccountTypeTableViewCell, collectionRow: Int) 
        print("collectionRow clicked:\(collectionRow)")
    

我试过delegate2?.navigationController?.pushViewController(signUpViewController, animated: true),它无法推送到signUpViewController。

我也试过delegate?.OpenNows(wasPressedOnCell: self) 也无法推送到signUpViewController。

我还想在 collectionView 单元格中获取 tableView 行,该怎么做?

请帮助我更正我的代码,以便它可以推送到 signUpViewController 并在 collectionView 单元格中获取 tableView 行。

【问题讨论】:

您应该将UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout 推送到TableViewController,不要在tableViewCell 内处理它们,这样您就可以在没有其他代表的情况下轻松获取所选行,here 是一个例子 @Tj3n,问题是我的TableViewController是空的,在tableview里面,我叫AccountTypeTableViewCell xib,在AccountTypeTableViewCell里面我叫另一个xib(AccountTypeCell) AccountTypeTableViewCell xib 包括 UITableViewCell -> UICollectionView。 AccountTypeCell xib 包括 UICollectionViewCell 及其内容 【参考方案1】:

您可以简单地将推送的委托传递给所有这些质量之间的下一个 ViewController。请按照此步骤再次尝试您的委托,也许您忘记在嵌套组件中进行设置....

//带有委托功能的ViewControllerExtension

extension AccountTypeViewController:CustomCollectionCellDelegate 
    func OpenNows(wasPressedOnCell cell: AccountTypeCollectionViewCell?) 
        print("hasil nya eh dipencet")
        let accountRegular = Account(accountType: "signUp.accountTypeRegular".localized(), code: AccountType.regular)
        let signUpViewController = SignUpViewController.fromStoryboard(name: AppStoryboard.Signup.instance)
        let signUpViewModel = SignupViewModel.shared
        signUpViewModel.accountType = accountRegular
        signUpViewController.signupViewModel = signUpViewModel
        navigationController?.pushViewController(signUpViewController, animated: true)
    

    func collectionView(collectioncell: AccountTypeCollectionViewCell?, didTappedInTableview TableCell: AccountTypeTableViewCell, collectionRow: Int) 
        print("collectionRow clicked:\(collectionRow)")
    

// 将自己设置为表格单元格中的委托的 ViewController...

class AccountTypeViewController: UIViewController 
     //......
     //multiple code
     //......

     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
          //when you dequeue your cell insert the delegate
          // Everything I write next is pseudocode so do not simply copy+paste
          let cell = AccountTypeTableViewCell()
          cell.delegate = self
          return cell
     


// 使用嵌套CollectionCells中ViewController设置的委托的表格单元

class AccountTypeTableViewCell: UITableViewCell, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout 
     weak var cellDelegate: CustomCollectionCellDelegate?

     //......
     //multiple code
     //......

     func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
           //when you dequeue your cell insert the delegate
           // Everything I write next is pseudocode so do not simply copy+paste
           let cell = AccountTypeCollectionViewCell()
           cell.delegate = cellDelegate
           return cell
     

// CollectionCell 触发嵌套在组件之间的委托函数

class AccountTypeCollectionViewCell: UICollectionViewCell 
     //......
     //Multiple component
     //......
     weak var delegate: CustomCollectionCellDelegate?

     @IBAction func btnMoreInfoPressed(_ sender: UIButton) 
         print("btnMoreInfoPressed eh dipencet")
         delegate?.OpenNows(wasPressedOnCell: self)
     
 

试试这个,让你的代码更简单,更简洁,以简化你未来的调整:) 告诉我它是否有效

【讨论】:

它没有工作,因为它没有从xib加载customCell和CustomCell,所以UI变成空白。 哦!您可以简单地删除此类 var customCell : AccountTypeTableViewCell let cell = Bundle.main.loadNibNamed("AccountTypeTableViewCell", owner: self, options: nil)?.last return cell as! AccountTypeTableViewCell 并在 viewDidLoad() 中使用此代码 table.register(UINib(nibName: "AccountTypeTableViewCell", bundle: nil), forCellWithReuseIdentifier: cellReuseId) 按照本教程学习如何将 reusableCell 与 Xib 或 Nib 一起使用 ios-tutorial.com/custom-uitableviewcell-xib-swift-3 我将 tableView 单元格 xib 的自定义单元格放入 tableView 单元格中,代码为 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell var cell = tableView.dequeueReusableCell(withIdentifier: "AccountTypeTableViewCell “) 作为? AccountTypeTableViewCell if cell == nil cell = AccountTypeTableViewCell.customCell cell?.collectionView.tag = indexPath.row 返回单元格! ,因为我想在每个 tableView 行(如 playstore 或 appstore)显示不同的 collectionView。 嗯,可能当您将集合视图嵌套在表格单元格中时,找不到它并且它显示任何内容,尝试创建一个新的视图控制器并按照以下步骤操作ashfurrow.com/blog/…。尝试用你的代码重复它,看看你是否遗漏了什么:) 我得到了“btnMoreInfoPressed eh dipencet”的日志,但没有得到“hasil nya eh dipencet”的日志。这意味着它没有扩展 AccountTypeViewController:CustomCollectionCellDelegate (delegate?.OpenNows(wasPressedOnCell: self) did not work)

以上是关于当点击collectionView单元格内的按钮时,如何从tableViewCell内的collectionView获取表视图行并推送到viewController的主要内容,如果未能解决你的问题,请参考以下文章

仅更改一个 collectionview 单元格的对象

tableView 单元格内的多个 collectionView 单元格在滚动时更改设计

Swift - 想要在单击集合视图单元格内的按钮时进行更改

当单元格具有动态宽度时,CollectionView 中的间距不正确?

向上传递 AVPlayerLayer 引用

使用Swift 3单击collectionView单元格内的项目时如何导航另一个视图控制器