Skip to content

Instantly share code, notes, and snippets.

@eoghain
Created March 5, 2014 00:16
Show Gist options
  • Select an option

  • Save eoghain/9358631 to your computer and use it in GitHub Desktop.

Select an option

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
@NikolayShubenkov
Copy link
Copy Markdown

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
Copy Markdown

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
Copy Markdown

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
Copy Markdown

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