简体   繁体   中英

Swift CollectionView Cell in a CollectionView Cell - Present New View Controller

在此处输入图像描述

Hello all,

I am having trouble with the logic around presenting new views from nested CollectionView cells.

From the HomeVC (cell1), I have another collection view nested with 4 additional cells. When the user clicks on the respective cell, I'd like to take them to another view controller. Workflow indicated by green arrows under cell 1 in the image.

What is the best way to achieve this?

I've tried the suggestion here: Presenting a ViewController from within a CollectionViewCell that is nested in a TableViewCell but the "nesting of collectionview cells" is what's throwing me off.

Appreciate the insight!

UPDATED WITH CODE BELOW

//HomeVC.swift -  
class HomeVC: UIViewController {

extension HomeVC: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    
    if indexPath.item == 0 {
         let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! SectionCell
        

        return cell
    }

//SectionCell.swift - Menu item 1
class SectionCell: UICollectionViewCell, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, CellDelegate {

func aboutCategorySelected(_ indexPath: IndexPath) {
    
    switch indexPath.item {
      case 0: //go to new VC1
      case 1: //go to new VC2
      case 2: //go to new VC3
      case 3: //go to new VC4
      default: break

    }
    

}

lazy var collectionView : UICollectionView = {
    let layout = UICollectionViewFlowLayout()
    let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
    cv.translatesAutoresizingMaskIntoConstraints = false
    cv.backgroundColor = .init(white: 0.9, alpha: 1)
    cv.delegate = self
    cv.dataSource = self
    
    return cv
}()

override init(frame: CGRect) {
    super.init(frame: frame)
    //register nested cv cell
    collectionView.register(AboutCell.self, forCellWithReuseIdentifier: "aboutCell")
    
}

 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

 if indexPath.item == 2 {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "aboutCell", for: indexPath) as! AboutCell
        
        cell.delegate = self
        
        return cell
    }
 }

 //AboutCell.swift - this is the nested cell
 protocol CellDelegate {

func aboutCategorySelected(_ indexPath : IndexPath)
}

 class AboutCell: UICollectionViewCell, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {

var delegate: CellDelegate?


func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 4
    }
    
    
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    delegate?.aboutCategorySelected(indexPath)
}

updating the answer as your code you musta add a closure to the sectionCell like this and update the cell for item to respond to closure, and perform a segue in that case.

    extension HomeVC: UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    
    if indexPath.item == 0 {
         let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! SectionCell
        cell.completion = {[weak self] val in
            guard let self = self else {return}
            self.performSegue(withIdentifier: val.row.description, sender: nil)
        }
        return cell
    }
}
//SectionCell.swift - Menu item 1
class SectionCell: UICollectionViewCell, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, CellDelegate {
    var completion: ((IndexPath)->Void)?

func aboutCategorySelected(_ indexPath: IndexPath) {
    completion?(indexPath)
}

since you not provide code to handle the segue and what identifier do you use I posted a simple way using index path.row as simple string for segue identifier. adapt you your need also if toy need to pass data to the next vc. take into account. PD. in your About cell you have a delegate var that is the Section cell class, what you need is a way that class Section cell after receiving action from about cell tell the VC that it must perform an action and with a closure you could do it, there is another way using another delegate for the Section cell in the viewController but the closure is my preferred one.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM