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.