user1093111
user1093111

Reputation: 1111

Adding two UICollectionViews in a ViewController with stores programmatically

Trying to jump ship from storyboards. I'm trying to put two UIViewControllers into a view, and scroll horizontally.

So first, I go into app delegate

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    window = UIWindow(frame: UIScreen.main.bounds);
    window?.makeKeyAndVisible()

    var homeViewController = ViewController()
    let shirtStore = ShirtStore()
    let pantStore = PantStore()
    homeViewController.shirtStore = shirtStore
    homeViewController.pantStore = pantStore

    window?.rootViewController = UINavigationController(rootViewController: ViewController())


    return true
}

I'm not sure if I loaded that first homeViewController.

Then, in my ViewController I have:

import UIKit

class ViewController: UIViewController, 
UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {



let collectionViewShirts = UICollectionView()
let collectionViewPants = UICollectionView()
let collectionViewShirtsIdentifier = "CollectionViewShirtsCell"
let collectionViewPantsIdentifier = "CollectionViewPantsCell"

var shirtStore: ShirtStore!
var pantStore: PantStore!

override func viewDidLoad() {
    super.viewDidLoad()
    navigationItem.title = "Hanger"

    view.backgroundColor = UIColor.red

    collectionViewShirts.delegate = self
    collectionViewPants.delegate = self

    collectionViewShirts.dataSource = self
    collectionViewPants.dataSource = self

    self.view.addSubview(collectionViewShirts)
    self.view.addSubview(collectionViewPants)

    collectionViewShirts.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "CollectionViewShirtsCell")
}

       func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

if collectionView == self.collectionViewShirts {
        let cellA = collectionView.dequeueReusableCell(withReuseIdentifier: collectionViewShirtsIdentifier, for:  indexPath as IndexPath)

        // Set up cell
        cellA.backgroundColor = UIColor.blue
        return cellA
    }

    else {
        let cellB = collectionView.dequeueReusableCell(withReuseIdentifier: collectionViewPantsIdentifier, for: indexPath as IndexPath)

        // ...Set up cell
         cellB.backgroundColor = UIColor.red
        return cellB
    }
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int{
    if(collectionView == collectionViewShirts)
    {
        return shirtStore.allShirts.count
    }
    else if (collectionView == collectionViewPants)
    {

        return 5//pantStore.allPants.count
    }
    else
    {
        return 5//shoeStore.allShoes.count
    }
  }
}

My app is terminating due to a nil layout parameter. What am I missing. There are no warnings upon build.

Upvotes: 1

Views: 129

Answers (2)

Abdelahad Darwish
Abdelahad Darwish

Reputation: 6067

Just add UICollectionViewFlowLayout to your Collection View

 public var collectionViewShirts : UICollectionView{

        let layout = UICollectionViewFlowLayout()
        let collectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
        collectionView.delegate = self
        collectionView.dataSource = self
        return collectionView

    }
    public var collectionViewPants :UICollectionView{

        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = UICollectionViewScrollDirection.horizontal

        let collectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
        collectionView.delegate = self
        collectionView.dataSource = self
        return collectionView

    }

Upvotes: 1

nathangitter
nathangitter

Reputation: 9787

You cannot initialize a UICollectionView with no arguments. You need to provide a collectionViewLayout parameter so the collection view knows how to arrange its content.

Instead, create a layout object and use it to initialize the collection view. A nice way to do this in Swift is to use lazy closures to initialize properties.

public lazy var collectionViewShirts: UICollectionView = {
    let layout = UICollectionViewFlowLayout()
    let collectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
    collectionView.delegate = self
    collectionView.dataSource = self
    // any other configuration here
    return collectionView
}()

Upvotes: 1

Related Questions