In other words -- how do you know, inside a UICollectionViewFlowLayout, when the associated collection view has had the data reloaded?
I'm using the popular and awesome BPXLFlowLayout
by Brandon Alexander,
This is the best way to make "bouncy" collections, such as the iOS Messages app.
How to replicate Messages bouncing bubbles in iOS 7
I found a real problem in BPXLFlowLayout and other UICollectionViewFlowLayout approaches. Typically, you only "use them once" with the one layout, the one collection view. Say you have a collection view "BouncyViewHouses"
@interface BouncyViewHouses : UICollectionViewController
which uses BPXLFlowLayout
Everything's great until you reload. Or confusingly to me, if you use the same BPXLFlowLayout on ANOTHER collection view, you seem to have the same problem.
To fix the problem, you have to do something like this
@implementation BouncyViewHouses
-(void)safelyReloadBouncyTable
{
[self.collectionView reloadData];
[(BPXLFlowLayout *)self.collectionView.collectionViewLayout fastSignal];
}
Whenever you reload the collection, you have to "MANUALLY" zero out the animator.
So for example inside BPXLFlowLayout I added a new method ...
@interface BPXLFlowLayout ()
@property (nonatomic, strong) UIDynamicAnimator *animator;
@end
@implementation BPXLFlowLayout
-(void)fastSignal
{
// it's very difficult to have prepareLayout (or, anything) called when you
// reload the collection data. in fact, you must call this manually.
self.animator = nil;
}
and I have to call that MANUALLY from collection views, when I reload the data source.
(If you don't do this, you'll get really hairy problems that are hard to figure out!)
My problem .. you'd think that inside BPXLFlowLayout (or similar) you could just call self.animator = nil;
inside -(void)prepareLayout
or perhaps shouldInvalidateLayoutForBoundsChange:
but it doesn't work! I tried everything, in a word I can't figure out "what is triggered" inside a UICollectionViewFlowLayout, when the data source is reloaded on the associated collection view.
I guess it's possible, NOTHING is really triggered in a UICollectionViewFlowLayout .. in that case, my approach, of adding a manual tickle which you "must call" when you reload data, I guess that's the only way.