UICollectionView state restoration: customizing scroll position

As you already pointed out, UIDataSourceModelAssociation doesn't seem to work with restoring a UICollectionView's visible offset, but only for selected items. I tried setting breakpoints on both modelIdentifierForElementAtIndexPath and indexPathForElementWithModelIdentifier and noticed they were only called after I selected a cell. If I cleared my collection view's selected cells before backgrounding my app then modelIdentifierForElementAtIndexPath wouldn't get called, but it would once I set at least one cell as selected. At least I can verify that you aren't the only one seeing this behavior.

I think because of the varying nature of UICollectionView it is probably not straightforward to create behavior that scrolls visible cells to the correct point, but this obviously isn't reflected in Apple's documentation. Manually encoding an identifier to the first visible cell for your layout should be a good alternative. What I'm doing is wrapping the collection view's scroll offset in an NSValue and restoring that:

var collectionView: UICollectionView?

// ...

override func encodeRestorableStateWithCoder(coder: NSCoder) {
    if let view = collectionView, offsetValue = NSValue(CGPoint: view.contentOffset) {
        coder.encodeObject(offsetValue, forKey: CollectionViewContentOffsetKey)
    }

    super.encodeRestorableStateWithCoder(coder)
}

override func decodeRestorableStateWithCoder(coder: NSCoder) {
    if let offsetValue = coder.decodeObjectForKey(CollectionViewContentOffsetKey) as? NSValue {
        collectionView?.setContentOffset(offsetValue.CGPointValue(), animated: false)
    }

    super.decodeRestorableStateWithCoder(coder)
}