Search code examples
iosswiftuitableviewuicollectionviewprotocols

Perform segue from CollectionCell inside tableview


How to perform segue from collectioncell inside tableview? I have created a collectionview inside tableview and I want perform segue from collectioncell to another veiwcontroller. Each cell has its own segue. For example, " if indexpath.row = 0 perform segue to identifier "A" if indexpath.row == 1 perferom segue to idetifier "B". Thanks, Here is my code.

   import UIKit

   protocol SegueSelectionDelegate: class {
    
   func didSelect()
    
   }

   class ProductCell: UITableViewCell,UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {
    
   weak var delegate: SegueSelectionDelegate?
    
    
       var productArray:[(names:String,image:String)] =
           []
    
        @IBOutlet weak var collectionView: UICollectionView!{
          didSet{
              self.collectionView.delegate = self
              self.collectionView.dataSource = self
              
              self.collectionView.register(UINib(nibName: "CategoriesTwoCollCell", bundle: nil), 
              forCellWithReuseIdentifier: "cell")
              self.collectionView.reloadData()
          }
      }
    
          override func awakeFromNib() {
           super.awakeFromNib()
        // Initialization code
        
               productArray.append((names: "Bicycles", image: "KIA"))
               productArray.append((names: "Motorbikes", image: "Lotus"))
               productArray.append((names: "Fabric Safe",  image: "Mini"))
               productArray.append((names: "gas",  image: "Nissan"))
               productArray.append((names: "gas",  image: "Mercedes"))

               
               }

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

                 // Configure the view for the selected state
                }
    
                 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection 
 section: Int) -> Int {
        
           return productArray.count
        
         }
         
         func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
           let cell = self.collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CategoriesTwoCollCell
           cell.titleProductlbl.text = self.productArray[indexPath.row].names
          //   cell.renlbl.text = self.productArray[indexPath.row].rent
           cell.imageView.image = UIImage(named:self.productArray[indexPath.row].image)
         
           return cell
         }
       
       func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
           
              return CGSize(width: 85, height: 90)
         }
    
            func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        
      
           delegate?.didSelect()
       
        }

       }


 

     class MainTableViewController: UIViewController,MainTableViewCellDelegate ,SegueSelectionDelegate {

     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier:"productcell1" , for: indexPath) as! ProductCell
                
                cell.delegate = self
                     
            return cell
            
            }     
        
}

 func didSelect() {
        
   // how can i add indexpath.row  as showen below it wont allow me to do it?

    if indexpath.row == 0 {
        
         performSegue(withIdentifier: "BicyclesOptionseg", sender: self)
                
        
    } else {
   
    if indexpath.row == 2 {

   performSegue(withIdentifier: "CarsOptionseg", sender: self)
  }

 }

Solution

  • To solve this problem, you can just add the required parameter to your delegate method. Looks like you don't need the whole IndexPath, just the row so do this:

    protocol SegueSelectionDelegate: class {
        func didSelect(index: Int) // Can also change the parameter to IndexPath if you want but not necessary
    }
    

    Then in the collectionView didSelect method:

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        delegate?.didSelect(index: indexPath.row)
    }
    

    Finally in MainTableViewController:

    class MainTableViewController: UIViewController, MainTableViewCellDelegate , SegueSelectionDelegate {
        func didSelect(index: Int) {
            // Now you have access to index and can use it
            if index == 0 {
                performSegue(withIdentifier: "BicyclesOptionseg", sender: self)
            }
        }
    }