Search code examples
swiftxcodeuicollectionviewswift5xcode13

Adding a Second CollectionView


In my attempt to add a second CollectionView I have became lost. Here is my future project and I was essentially trying to duplicate that (The reason for the Second collectionView is so that I will have 4 rows, but the top two and bottom two will scroll independently).

Here is the storyboard for reference.

I however get this error here (Second Photo): here

Here is my code for the originally ViewController (WORKING)

Followed by the SecondViewController code, which has caused the app to display the message above.

  import UIKit

  class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {


@IBOutlet var collectionViewButtons: UICollectionView!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    collectionViewButtons.delegate = self
    collectionViewButtons.dataSource = self
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 6 //number of buttons
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! ButtonCollectionViewCell
    
    cell.buttonLive.setTitle("Handling a Breakup", for: .normal) //set button title
cell.buttonLive.titleLabel!.font = UIFont(name: "Marker Felt", size: 20)
    cell.buttonLive.layer.cornerRadius = 10
    cell.buttonLive.clipsToBounds = true
    cell.buttonLive.layer.borderWidth = 1.0
    cell.buttonLive.layer.borderColor = UIColor.white.cgColor

    if indexPath.item == 0 { //first button
        cell.buttonLive.backgroundColor = UIColor.darkGray //set button background
    }
    else if indexPath.item == 1 { //second button
        cell.buttonLive.backgroundColor = UIColor.systemGray
        cell.buttonLive.setTitle("Good Work", for: .normal)

    }
    else if indexPath.item == 2 { //3rd button
        cell.buttonLive.backgroundColor = UIColor.darkGray
    }
    else { // for remaining buttons
        cell.buttonLive.backgroundColor = UIColor.darkGray
    }
    
    return cell
}
   func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    if indexPath.item == 0 { // opens any page by clicking button 1
  //      let vc = storyboard?.instantiateViewController(withIdentifier: "anyVC1") as! ViewController1
//        navigationController?.pushViewController(vc, animated: true)
      //      }
    //      else if indexPath.item == 1 {
    //          let vc = storyboard?.instantiateViewController(withIdentifier: "anyVC2") as! ViewController2
  //      navigationController?.pushViewController(vc, animated: true)
    }
    //      else if indexPath.item == 2 {
    //          let vc = storyboard?.instantiateViewController(withIdentifier: "anyVC3") as! ViewController3
   //          navigationController?.pushViewController(vc, animated: true)
         }
         //      else {
         //         let vc = storyboard?.instantiateViewController(withIdentifier: "anyVC4") as! ViewController4
          //      navigationController?.pushViewController(vc, animated: true)
    }
    //  }

    //}
    // You can return any number of buttons by changing return 6 to any required num

SECOND VIEW CONTROLLER:

    import UIKit


    class SecondViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {

override func viewDidLoad() {
    super.viewDidLoad()

        // Do any additional setup after loading the view.

    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 6 //number of buttons
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let SecondCell = collectionView.dequeueReusableCell(withReuseIdentifier: "SecondCell", for: indexPath) as! ButtonCollectionViewCell
        
        SecondCell.buttonTwo.setTitle("Handling a Breakup", for: .normal) //set button title
    SecondCell.buttonLive.titleLabel!.font = UIFont(name: "Marker Felt", size: 20)
        SecondCell.buttonTwo.layer.cornerRadius = 10
        SecondCell.buttonTwo.clipsToBounds = true
        SecondCell.buttonTwo.layer.borderWidth = 1.0
        SecondCell.buttonTwo.layer.borderColor = UIColor.white.cgColor

        if indexPath.item == 0 { //first button
            SecondCell.buttonTwo.backgroundColor = UIColor.darkGray //set button background
        }
        else if indexPath.item == 1 { //second button
            SecondCell.buttonTwo.backgroundColor = UIColor.systemGray
            SecondCell.buttonTwo.setTitle("Good Work", for: .normal)

        }
        else if indexPath.item == 2 { //3rd button
            SecondCell.buttonTwo.backgroundColor = UIColor.darkGray
        }
        else { // for remaining buttons
            SecondCell.buttonTwo.backgroundColor = UIColor.darkGray
        }
        
        return SecondCell
    }
       func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        if indexPath.item == 0 { // opens any page by clicking button 1
      //      let vc = storyboard?.instantiateViewController(withIdentifier: "anyVC1") as! ViewController1
    //        navigationController?.pushViewController(vc, animated: true)
  //      }
  //      else if indexPath.item == 1 {
  //          let vc = storyboard?.instantiateViewController(withIdentifier: "anyVC2") as! ViewController2
      //      navigationController?.pushViewController(vc, animated: true)
        }
  //      else if indexPath.item == 2 {
  //          let vc = storyboard?.instantiateViewController(withIdentifier: "anyVC3") as! ViewController3
  //          navigationController?.pushViewController(vc, animated: true)
        }
  //      else {
   //         let vc = storyboard?.instantiateViewController(withIdentifier: "anyVC4") as! ViewController4
      //      navigationController?.pushViewController(vc, animated: true)
        }
  //  }
    
//}
// You can return any number of buttons by changing return 6 to any required num

Notes: I have also gone through and done the following to no success: Changed all "collectionView" writings to say "SecondCollection" because that is what my second collectionView is named.

I have set a Collection IBOutlet for both collectionView. I have set a separate IBOutlet for both buttons.


Solution

  • If you want two (or more) collection views, you don't want two controllers... you need to check which collection view is requesting data (or being interacted with) and return the appropriate information.

    So, your class will look something like this:

    class TwoCollectionsViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
        
        @IBOutlet var firstCV: UICollectionView!
        @IBOutlet var secondCV: UICollectionView!
    
        let firstData: [String] = [
            "Btn 1", "Btn 2", "Btn 3", "Btn 4", "Btn 5",
        ]
        let secondData: [String] = [
            "Second 1", "Second 2", "Second 3", "Second 4"
        ]
    
        override func viewDidLoad() {
            super.viewDidLoad()
            
            firstCV.dataSource = self
            firstCV.delegate = self
            
            secondCV.dataSource = self
            secondCV.delegate = self
        }
        
        func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    
            // if it's the First Collection View
            if collectionView == firstCV {
                return firstData.count
            }
    
            // it's not the First Collection View, so it's the Second one
            return secondData.count
        }
        
        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            
            // if it's the First Collection View
            if collectionView == firstCV {
                let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "firstCell", for: indexPath) as! FirstCollectionViewCell
                cell.buttonOne.setTitle(firstData[indexPath.item], for: [])
                return cell
            }
            
            // it's not the First Collection View, so it's the Second one
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "secondCell", for: indexPath) as! SecondCollectionViewCell
            cell.buttonTwo.setTitle(secondData[indexPath.item], for: [])
            return cell
    
        }
    
        func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    
            // if it's the First Collection View
            if collectionView == firstCV {
                // do what you want because a cell in the First Collection View was selected
                return
            }
            
            // it's not the First Collection View, so it's the Second one
            // do what you want because a cell in the Second Collection View was selected
            
        }
        
    }