Search code examples
iosobjective-clayoutuicollectionviewuicollectionviewlayout

Custom UICollectionViewLayout animation issues


I developed a custom UICollectionViewLayout to handle some advanced layout requirements on a clients application what seems to work really well.. Until I start trying to use animations.

I took some time out of work to document and make it a bit more flexible so it can be found here: https://github.com/liamnichols/LNCollectionViewPagedLayout.

Its purpose is to page the content onto new pages if it will not fit on the previous page to ensure that the content does not get cut across two pages and it seems to handle this OK.

I noticed from the start that there where animation issues with it however I never needed to use animations originally so didn't attempt to investigate/fix although now its become a requirement that a UICollectionViewCell can expand revealing some more content and when I attempt to use any form of animation methods (reloadRowsAtIndexPaths:, performBatchUpdates:completion: ect) I always get very strange behaviour ranging from crashes (view argument is nil) to messed up layouts.

Currently my layout works by creating a dictionary of UICollectionViewLayoutAttributes on prepareLayout by asking the delegate for the size of each cell then running some logic to see if it will fit or not and so on...

When the layoutAttributesForElementsInRect: method is called, it can then simply query the dictionary and fetch an array of attributes that are relevant for that rect.

First off, is that the best way to go about creating this layout? I found it very hard to find documentation on creating custom layouts to meet my needs and ended up looking at other open source libraries for pointers on what to do.

Secondly, I haven't implemented the initial/final layout attribute methods as I cannot figure out how to correctly use them. Is this the reason I'm having issues or are these optional?

Any help or pointers to correctly creating UICollectionViewLayouts would be great.


Solution

  • For issues with expanding cells (or just cells changing size in general), this answer may be helpful. The short answer is that the default implementation of initialLayoutAttributesForAppearingItemAtIndexPath: (and, in general, all of the initial/final layout attribute methods) doesn't always return the correct frame and you've got to override this method and fix the errors.

    Debugging these types of issues is fairly straightforward. Start by logging the attributes being returned with something like this

    - (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath {
        UICollectionViewLayoutAttributes *attributes = [super initialLayoutAttributesForAppearingItemAtIndexPath:itemIndexPath];
        NSLog(@"indexPath=%@, attributes=%@", itemIndexPath, attributes);
        return attributes;
    }
    

    and determine when the frames are incorrect. From there you can come up with an approach to correct the errors. Thats about as detailed as I can get without knowing more specifics.