0

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.

  • This is rather confusing... are you trying to display two horizontal-scrolling collection views on one view (in one view controller)? – DonMag Jun 08 '22 at 15:57
  • @DonMag I am trying to have two horizontal scrolling views within my app. (In the future there will be far more horizontal scroll collection views). I added a second collectionView and created a file for it and attempted to edit but failed and that is the code you see that says “second view controller” – Dakota Davis Jun 09 '22 at 16:41

1 Answers1

1

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
        
    }
    
}
DonMag
  • 69,424
  • 5
  • 50
  • 86
  • I have gone ahead and attempted this code, I do however run into: "this class is not key value coding-compliant for the key firstCV." I have checked IBconnections all around, as well as file types or any other error in code. I have my two buttons (since there is two collection views) on a second UICollectionViewCell file. Any ideas? – Dakota Davis Jun 10 '22 at 10:50
  • @DakotaDavis - if you get *"this class is not key value coding-compliant for the key firstCV."* then your `@IBOutlet` is *not* setup correctly. I put a complete example (note: ***example only***) here: https://github.com/DonMag/TwoCVs – DonMag Jun 10 '22 at 11:57