Most iOS Developers Use UICollectionView, And Equally-Spaced Cells Should Be Built-In
The Problem
Apple’s iOS classes UICollectionView and UICollectionViewFlowLayout are used by many app developers, and for the most part these classes work well together and don’t require too much customization, but one thing they don’t do well is automatically spacing cells out for all device layouts.
I found this very issue when developing an app that was responsible for showing thumbnails of photos from a large organization’s REST services. With the default values, or even with slightly adjusted values, my layout looked something like the following screenshots.
iPhone 5s, Portrait Mode
iPhone 5s, Landscape Mode
iPhone 6s, Portrait Mode
iPhone 6s, Landscape Mode
iPad, Portrait Mode
iPad, Landscape Mode
While the horizontal white space between cells may be fine, the vertical white space is either non-existent or not consistent with the horizontal white space; also, it would be nice to have a little white space around the edges of the screen. It is possible to adjust these values, but each value can be different for each device and orientation. Currently, neither Xcode’s Interface Builder editor nor the class UICollectionViewFlowLayout provide a means to set these values automatically.
Collection View Flow Layout in Interface Builder
The Solution
To fix this issue, I wrote a subclass of UICollectionViewFlowLayout called DSSCollectionViewFlowLayout which overrides the method prepareLayout to calculate the values needed for the properties minimumLineSpacing, minimumInteritemSpacing, and sectionInset so all have the same value whenever the user changes the orientation of the device or layout of the application. With this change, the white space around each cell is far more pleasing.
iPhone 5s, Portrait Mode
iPhone 5s, Landscape Mode
iPhone 6s, Portrait Mode
iPhone 6s, Landscape Mode
iPad, Portrait Mode
iPad, Landscape Mode
While the amount of white space around each cell is different across devices and orientations, the amount is consistent within a particular layout.
When developing software for Apple’s platforms, I prefer adding settings within storyboards and XIBs/NIBs as much as possible over writing source code, so I decided to add the property placeEqualSpaceAroundAllCells to my subclass so I could turn on or off this functionality within my collection view’s resource Identity Inspector panel.
Collection View Flow Layout in the Document Outline
Identity Inspector of the Collection View Flow Layout
The Objective-C header for my subclass DSSCollectionViewFlowLayout declares the property placeEqualSpaceAroundAllCells so my version of prepareLayout will know whether or not to perform the equidistant white space calculation.
DSSCollectionViewFlowLayout.h
The Objective-C source for my subclass’s implementation of prepareLayout shows how I calculated the right amount of space whether scrolling horizontally or vertically.
DSSCollectionViewFlowLayout.m
And, for fun, I wrote a Swift version, too.
DSSCollectionViewFlowLayout.swift
I’ve currently only used this code with square and rectangular fixed-sized cells, but it should also work with collection views with variable-sized cells.