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)
}