27

At UITableView, completely static tableView config is possible. You can disconnect UITableView's datasource and put each cell on storyboard(or xib) by using IB.

I tried same thing with UICollectionView. disconnect UICollectionView's datasource. Put each cell on UICollectionView on storyboard. I built it without any errors. But it didin't work. cells were not displayed at all.

Is UICollectionView without datasource possible?

kmugitani
  • 615
  • 1
  • 6
  • 13
  • When you build your cells in `cellForItemAtIndexPath` you could access a static array of cells rather than using `dequeueReusableCellWithReuseIdentifier`. I would only do this if you have a really strong use case for it though, as it's more likely to lead to bugs and performance issues. – Kyle Clegg Apr 11 '16 at 21:20

3 Answers3

18

No.

Creating a static UICollectionViewController is not allowed. You must have a data source delegate.

I also want to point out that there is not a static UITableView, but a static UITableViewController. It's a difference.

Community
  • 1
  • 1
AShavit
  • 416
  • 3
  • 10
  • 1
    Ok. But what is your basis? Apple documents? Apple UIKit designer's response thay you got? Or your experience? – kmugitani Feb 16 '15 at 08:44
  • Experience. I didn't look it up, but you can see in IB that unlike UITableViewController, the UICollection VC doesn't give you an option to use static collection. You can also see that adding more cells in the collection view is just adding cell formats. – AShavit Feb 17 '15 at 14:52
18

You can easily create a static UICollectionViewController.

Just create every cell in interface builder, give them re-use identifiers(e.g. "Home_1" "Home_2" "Home_3"), and populate the methods as follows:

class HomeViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {  
    let cellIdentifiers:[String] = ["Home_1","Home_2","Home_3"]
    let sizes:[CGSize] = [CGSize(width:320, height:260),CGSize(width:320, height:160),CGSize(width:320, height:100)]

    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return cellIdentifiers.count
    }
    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        return collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifiers[indexPath.item], for: indexPath)
    }
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return sizes[indexPath.item]
    }
}

Then set the view controller to be of the proper class, and, hey presto, a (basically) static collection. I'm sorry to say but this is BY FAR the best way to support portrait and landscape views when you have groups of controls...

Elijah
  • 8,381
  • 2
  • 55
  • 49
Daniel K
  • 1,119
  • 10
  • 20
0

I did a little experimenting and wanted to add my own method since it helped me achieve the truly static, highly custom Collection View I was looking for.

You can create custom UICollectionViewCells for each cell you want to display in your Collection View, and register them with all the Cell IDs in your Collection View, like this:

Create your static cell:

class MyRedCell: UICollectionViewCell {
    override init(frame: CGRect) {
        super.init(frame: frame)
        contentView.backgroundColor = .red
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

Make as many of these as you want.

And then back in your Collection View Controller, register them with their corresponding cellId:

let cellIds = ["redCell","blueCell","greenCell"]

override func viewDidLoad() {
    super.viewDidLoad()
    collectionView.register(MyRedCell.self, forCellWithReuseIdentifier: "redCell")
    collectionView.register(MyBlueCell.self, forCellWithReuseIdentifier: "blueCell")
    collectionView.register(MyGreenCell.self, forCellWithReuseIdentifier: "greenCell")
}

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIds[indexPath.item], for: indexPath)

    return cell
}

Each cell will display exactly what's in its class.

Tim Isenman
  • 147
  • 10