Home > Software design >  How to placed collectionView in respective tableView Section
How to placed collectionView in respective tableView Section

Time:10-19

I have two collectionViews CollectionViewCell and CollectionViewCellButton that i want to place in first and second section of tableView respectively. I am debugging it by setting break point .

Here is my tableView.swift file cellForRowAt indexPath

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
       
 if indexPath.section == 0{
        if let cell = tableView.dequeueReusableCell(withIdentifier: "tableviewcellid", for: indexPath) as? TableViewCell {
           
            // Show SubCategory Title

            (colorsArray.objectsArray[indexPath.section] as! TableViewCellModel).headerButton.setTitle("View All",for: .normal)


            cell.category.text = (colorsArray.objectsArray[indexPath.section] as! TableViewCellModel).category
            cell.headerButton.setTitle("View All", for: .normal)
          // Pass the data to colletionview inside the tableviewcell

            // debugging...
                    
            let v1 = colorsArray.objectsArray[indexPath.section]
                    
            // what is v1?
            print(type(of: v1))
                    
            guard let thisTableCellModel = v1 as? TableViewCellModel else {
                fatalError("Expected a TableViewCellModel !!!")
            }
                    
            let v3 = thisTableCellModel.colors[indexPath.row]

            // what is v3?
            print("123Array=",type(of: v3))  // this is an Array, not a CollectionViewCellModel
                    
            guard let rowArray = v3 as? [CollectionViewCellModel] else {
                fatalError("Expected a [CollectionViewCellModel] !!!")
            }
                    
            // if we get here, we have properly unwrapped
            //  an array of CollectionViewCellModel
                    
            // so, don't make it an Array of Array
            //cell.updateCellWith(row: [rowArray])
            print("rowArray1=",type(of: rowArray))
            
            cell.updateCellWith(row: rowArray)
 
            
            cell.selectionStyle = .none

            return cell
       }
        }
    
else if indexPath.section == 1{
        if let cell = tableView.dequeueReusableCell(withIdentifier: "tableviewcellid", for: indexPath) as? TableViewCell {
            
            (colorsArray.objectsArray[indexPath.section] as! TableViewCellModel).headerButton.setTitle("View All",for: .normal)


            cell.category.text = (colorsArray.objectsArray[indexPath.section] as! TableViewCellModel).category
            cell.headerButton.setTitle("View All", for: .normal)
          //  if let cell = ((colorsArray.objectsArray[indexPath.section] as! TableViewCellModel).colors as! CollectionViewCellModelButton)
            
            // debugging...
                    
            let v1 = colorsArray.objectsArray[indexPath.section]
                    
            // what is v1?
            print(type(of: v1))
                    
            guard let thisTableCellModel = v1 as? TableViewCellModel else {
                fatalError("Expected a TableViewCellModel !!!")
            }
                    
            let v3 = thisTableCellModel.colors[indexPath.row]

            // what is v3?
            print("123ArraynotNotmodel=",type(of: v3))  // this is an Array, not a CollectionViewCellModel
                    
            guard let rowArray = v3 as? [CollectionViewCellModelButton] else {
                fatalError("Expected a [CollectionViewCellModelButton] !!!")
            }
            
            print("rowArray2=",type(of: rowArray))

            
                    
            cell.updateCellWith(row: rowArray)   //break point
        }
    }
        return UITableViewCell()
    }

Here is updateCellWith method that is called in each section of tableView

  func updateCellWith(row: [CollectionViewModel]) {
            self.rowWithColors = row
            self.collectionView.reloadData()
    }

Here is TableViewCell.Swift file that has cellForItemAt indexPath for collectionView

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        if indexPath.section == 0
        {
        if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionviewcellid", for: indexPath) as? CollectionViewCell {
           // cell.imageView = UIImage(named: (rowWithColors?[indexPath.item].image)! )
          //  CollectionViewCellModel
            ///    [CollectionViewCellModelButton
            print("index1=",indexPath.section)
            cell.imageView.image = (self.rowWithColors?[indexPath.item] as! CollectionViewCellModel).imageView
            cell.dicountAmountLabel.text = (self.rowWithColors?[indexPath.item] as! CollectionViewCellModel).dicountAmountLabel
            cell.dicountLabel.text = (self.rowWithColors?[indexPath.item] as! CollectionViewCellModel).dicountLabel
            cell.customerTypeLabel.text = (self.rowWithColors?[indexPath.item] as! CollectionViewCellModel).customerTypeLabel
            
            cell.dicountAmountLabel.textColor = .white
            cell.dicountLabel.textColor = .white
            cell.customerTypeLabel.textColor = .white
            
            return cell
        }
        }
       else if indexPath.section == 1
        {
        print("index2=",indexPath.section)

        if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionviewcellButtonid", for: indexPath) as? CollectionViewCellButton {
           // cell.imageView = UIImage(named: (rowWithColors2?[indexPath.item].image)! )
          //if let model = self.rowWithColors?[indexPath.item] as? CollectionViewCellModelButton {
                //model.collectionButton.setTitle(model.collectionButton, for: .normal)
            //cell.collectionButton.titleLabel?.text = (self.rowWithColors?[indexPath.item] as! CollectionViewCellModelButton).collectionButton.setTitle("Hi", for: .normal)
            cell.collectionButton.setTitle("Hi", for: .normal)
            //
            return cell
            }
       
           
        }
        return UICollectionViewCell()
    }
    

On setting breakPoint in cell.updateCellWith(row: rowArray) in indexPath.section == 1 of cellForRowAt indexPath of tableView.The debugger does not enter into indexPath.section == 1 of collectionView function cellForItemAt indexPath it revisit indexPath.section == 0 of collectionView Just for both section 0 and 1 of tableView cellForRowAt indexPath

It enter into indexPath.section == 0 of collectionView function cellForItemAt indexPath and give run time error.How i can make it run section 1 of collectionView function on section 1 of tableView.How display both CollectionView on View ?Just like in this figure

enter image description here

You can download the code from this enter image description here

Clearly you are holding array of CollectionViewModel (which is a protocol) and there are two different classes that confirms to this protocol CollectionViewCellModel and CollectionViewCellModelButton

and you blindly force cast both type to CollectionViewCellModel using

(self.rowWithColors?[indexPath.item] as! CollectionViewCellModel).imageView

Hence the crash.

Whats the issue?

There are way too many, I'll point out few relevant in this context. Your collectionView inside TableViewCell always receives an array of either CollectionViewCellModel or CollectionViewCellModelButton (One dimensional array)

In your code you hard code number of sections as 1

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

But strangely in your cellForItemAt indexPath you start checking indexPath.section == 0 or indexPath.section == 1, how can indexPath.section ever be 1 if your number of sections is hardcoded as 1?

Much more strangely you try to type cast the element in array rowWithColors based on indexPath.section In your code you typecast (self.rowWithColors?[indexPath.item] as! CollectionViewCellModel) if indexPath.section == 0 and self.rowWithColors?[indexPath.item] as! CollectionViewCellModelButton if indexPath.section == 1

What you need?

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        if let collectionViewCellModel = self.rowWithColors?[indexPath.row] as? CollectionViewCellModel,
           let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionviewcellid", for: indexPath) as? CollectionViewCell {
            cell.imageView.image = collectionViewCellModel.imageView
            cell.dicountAmountLabel.text = collectionViewCellModel.dicountAmountLabel
            cell.dicountLabel.text = collectionViewCellModel.dicountLabel
            cell.customerTypeLabel.text = collectionViewCellModel.customerTypeLabel

            cell.dicountAmountLabel.textColor = .white
            cell.dicountLabel.textColor = .white
            cell.customerTypeLabel.textColor = .white
            return cell
        }
       if let collectionViewCellModelButton = self.rowWithColors?[indexPath.row] as? CollectionViewCellModelButton,
          let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionviewcellButtonid", for: indexPath) as? CollectionViewCellButton
        {
           //customise `CollectionViewCellButton` here with `collectionViewCellModelButton` data
           return cell
        }
        return UICollectionViewCell()
    }

O/P:

enter image description here

TIP:

Not sure why you have cellForItemAtIndexPath with incorrect signature again in the same file, its good that its not getting called, but it let me wondering why? My advice, delete it :)

  • Related