Animate changes in UICollectionViewFlowLayout
<p>I'm using a <code>UICollectionViewFlowLayout</code> to arrange view tiles in a horizontally scrolling view. By default, I make them square using the <code>UICollectionViewDelegateFlowLayout</code>:</p>

<pre><code>func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -&gt; CGSize {
    var nominalSize = CGSize(width: collectionView.frame.height, height: collectionView.frame.height)
    return nominalSize
}
</code></pre>

<p>This way I get square tiles, sized to whatever the current of the <code>collectionView</code> is. However, there is a condition where I modify that nominal size for some tiles, so it evolves a little to look like:</p>

<pre><code>func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -&gt; CGSize {
    var nominalSize = CGSize(width: collectionView.frame.height, height: collectionView.frame.height)
    if someTest(indexPath) {
        nominalSize = self.tweakNominalSize(nominalSize)
    }
    return nominalSize
}
</code></pre>

<p>What I haven't figured out is how to trigger the collection view to A) recall the delegate to relayout and B) how to make it animate the changes. </p>

<p>What I have tried:</p>

<p>1)</p>

<pre><code>self.myCollectionView.setNeedsLayout()
UIView.animateWithDuration(200.milliseconds) {
    self.myCollectionView.layoutIfNeeded()
}
</code></pre>

<p>This does nothing. <code>print()</code> statements in the delegate callback reveal that it is never called.</p>

<p>2) </p>

<pre><code>self.schedulesView.setCollectionViewLayout(
    self.schedulesView.collectionViewLayout,
    animated: true)
</code></pre>

<p>This also does nothing. I'm not sure if its being clever or what. Maybe it's smart enough to note that they're identical and opt out?</p>

<p>3)</p>

<pre><code>self.schedulesView.startInteractiveTransition(
    to: self.schedulesView.collectionViewLayout,
    completion: nil)
self.schedulesView.finishInteractiveTransition()
</code></pre>

<p>This does cause the layout to happen! But not animated at all. It just suddenly changes. It seems to keep the right side of the tile where it was, rather than the left AND it seems to happen distinctly after other UI changes I effected between the two calls.</p>