Skip to content

Instantly share code, notes, and snippets.

@eoghain
Created March 5, 2014 00:16
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eoghain/9358631 to your computer and use it in GitHub Desktop.
Save eoghain/9358631 to your computer and use it in GitHub Desktop.
When adding/removing/reloading cells in a UICollectionView using the FlowLayout the cells fade in/out. When doing things like updating a progress bar you get a lot of annoying flashing because of this, this category will prevent that. As an added benefit rotation animations will now show the cells moving into position.
//
// UICollectionViewFlowLayout+NoFade.m
//
// Created by Rob Booth on 3/4/14.
#import "UICollectionViewFlowLayout+NoFade.h"
#import <objc/runtime.h>
@implementation UICollectionViewFlowLayout (NoFade)
+ (void) load
{
Method original, swizzled;
original = class_getInstanceMethod(self, @selector(initialLayoutAttributesForAppearingItemAtIndexPath:));
swizzled = class_getInstanceMethod(self, @selector(noFadeInitialLayoutAttributesForAppearingItemAtIndexPath:));
method_exchangeImplementations(original, swizzled);
original = class_getInstanceMethod(self, @selector(finalLayoutAttributesForDisappearingItemAtIndexPath:));
swizzled = class_getInstanceMethod(self, @selector(noFadeFinalLayoutAttributesForDisappearingItemAtIndexPath:));
method_exchangeImplementations(original, swizzled);
}
- (UICollectionViewLayoutAttributes *)noFadeInitialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath
{
// Not recursive, due to method exhange in load above
// This is because we can't call super in a catagory
UICollectionViewLayoutAttributes * attributes = [self noFadeInitialLayoutAttributesForAppearingItemAtIndexPath:itemIndexPath];
attributes.alpha = 1.0;
return attributes;
}
- (UICollectionViewLayoutAttributes *)noFadeFinalLayoutAttributesForDisappearingItemAtIndexPath:(NSIndexPath *)itemIndexPath
{
// Not recursive, due to method exhange in load above
// This is because we can't call super in a catagory
UICollectionViewLayoutAttributes * attributes = [self noFadeFinalLayoutAttributesForDisappearingItemAtIndexPath:itemIndexPath];
attributes.alpha = 1.0;
return attributes;
}
@end
@nanako-sen
Copy link

Thanks so much for this.
I had this fading problem when animating the constraints on the CollectionView. The animation is way nicer now too. Good work!

@kong707
Copy link

kong707 commented Feb 5, 2015

Hi,
The header of collectionView is still blinking by using this category. Anyway to fix that ?

@NikolayShubenkovProgSchool

now app crashed if I try to show UIActivityViewContoller like this:

UIActivityViewController *activityViewController =
[[UIActivityViewController alloc] initWithActivityItems:@["text",[UIImage imageNamed:@"some image"]]
applicationActivities:nil];

platform:
xCode 7.2 (7C68) iOS 9.2 iphone 5 simulator
Do you have any suggestions how to fix this?

@JALsnipe
Copy link

Any idea how to do this in Swift? Overriding load isn't an option anymore, and swapping the methods in initialize will not prevent the recursive call.

@tooolbox
Copy link

tooolbox commented Feb 9, 2018

The modern way to do this would be subclassing the flow layout, like so:

import UIKit

class NoFadeFlowLayout: UICollectionViewFlowLayout {
    
    override func initialLayoutAttributesForAppearingItem(at itemIndexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        let attrs = super.initialLayoutAttributesForAppearingItem(at: itemIndexPath)
        attrs?.alpha = 1.0
        return attrs
    }
    
    override func finalLayoutAttributesForDisappearingItem(at itemIndexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        let attrs = super.finalLayoutAttributesForDisappearingItem(at: itemIndexPath)
        attrs?.alpha = 1.0
        return attrs
    }
    
}

@zolomatok
Copy link

zolomatok commented Sep 17, 2018

Thank you, @tooolbox!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment