Joe Joe - 1 year ago 63
Swift Question

UICollectionView with randomized reuseIdentifiers in 1 section

I have a UICollectionView with 16 cells. 1 of the cells (the Game Over cell) must be random. I would like to randomize the Game Over cell in the collection view.

I have it somewhat working by using different sections, but that defeats the purpose of visually blending in with the 16.

I also had it somewhat working by creating an array of strings, one of the strings being "GameOver" - and then I did a shuffle on the array to customize how this cell appears.

That also didn't work, because it did not give me IB control of the game over cell.

How can I use the storyboard by creating 2 prototype cell identifiers, to randomize 1 of the game over cells, and 15 normal cells on a collection view of 16 total cells?

Answer Source

Here's one fairly simple approach:

In your view controller, define a property to hold any array of cell reuse identifiers that can be referenced later. You can set an initial, non-random configuration, like this:

var reuseIdentifiers = ["GameOver", "Normal", "Normal", "Normal", "Normal", "Normal", "Normal", "Normal", "Normal", "Normal", "Normal", "Normal", "Normal", "Normal", "Normal", "Normal"]

Define the following method, and call it sometime during the initialization of your view controller, before the collectionView is shown on screen, and before each time the collection view data is reloaded:

func randomizeReuseIdentifiers() {
    var randomized = [String]()

    for _ in initialIdentifiers {
        let random = reuseIdentifiers.removeAtIndex(Int(arc4random_uniform(UInt32(reuseIdentifiers.count))))

    reuseIdentifiers = randomized

And then in your collectionView(cellForItemAtIndexPath:NSIndexPath) method, look up the matching reuseIdentifier for the current indexPath, like this:

func collectionView(_ collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let identifier = reuseIdentifiers[indexPath.item]
    return collectionView.dequeueReusableCellWithReuseIdentifier(identifier, forIndexPath: indexPath)

This approach also has the benefit of allowing you to add additional identifiers into the initial reuseIdentifiers array in the future, to include other types of cells in one or more random locations.