Skip to content

Instantly share code, notes, and snippets.

@zuccoi
Created March 26, 2014 11:33
Show Gist options
  • Save zuccoi/9781294 to your computer and use it in GitHub Desktop.
Save zuccoi/9781294 to your computer and use it in GitHub Desktop.
Mix-in protocol that forwards appearance methods to child view controllers
/*
RLRAppearanceForwarding.h
Copyright ©2014 Kazki Miura. All rights reserved.
*/
#import <UIKit/UIKit.h>
@protocol RLRAppearanceForwarding <NSObject>
@optional
- (BOOL)isAppearanceForwardingEnabled; // Make it property >>>
- (void)setAppearanceForwardingEnabled:(BOOL)enabled;
@end
/*
RLRAppearanceForwarding.m
Copyright ©2014 Kazki Miura. All rights reserved.
*/
#import "RLRAppearanceForwarding.h"
#import "REKit.h"
// Constants
static void *kLoadedKey = @"RLRAppearanceForwarding_loaded";
static void *kEnabledKey = @"RLRAppearanceForwarding_enabled";
static NSString *const kBlockKey = @"RLRAppearanceForwardingBlock";
@implementation UIViewController (RLRAppearanceForwarding)
+ (void)load
{
@autoreleasepool {
for (Class class in RESubclassesOfClass([UIViewController class], YES)) {
if ([class conformsToProtocol:@protocol(RLRAppearanceForwarding)]
&& ![[class superclass] conformsToProtocol:@protocol(RLRAppearanceForwarding)]
&& ![[class associatedValueForKey:kLoadedKey] boolValue]
){
// Raise loaded flag
[class setAssociatedValue:@(YES) forKey:kLoadedKey policy:OBJC_ASSOCIATION_RETAIN];
#pragma mark └ -[class isAppearanceForwardingEnabled]
RESetBlock(class, @selector(isAppearanceForwardingEnabled), NO, kBlockKey, ^(UIViewController<RLRAppearanceForwarding> *vc) {
// Return flag
NSNumber *boolNum;
boolNum = [vc associatedValueForKey:kEnabledKey];
return (boolNum ? [boolNum boolValue] : YES);
});
#pragma mark └ -[class setAppearanceForwardingEnabled:]
RESetBlock(class, @selector(setAppearanceForwardingEnabled:), NO, kBlockKey, ^(UIViewController<RLRAppearanceForwarding> *vc, BOOL enabled) {
// Set flag
[vc setAssociatedValue:@(enabled) forKey:kEnabledKey policy:OBJC_ASSOCIATION_RETAIN];
});
#pragma mark └ -[class shouldAutomaticallyForwardAppearanceMethods]
RESetBlock(class, @selector(shouldAutomaticallyForwardAppearanceMethods), NO, kBlockKey, ^(UIViewController<RLRAppearanceForwarding> *vc) {
return ![vc isAppearanceForwardingEnabled];
});
#pragma mark └ -[class viewWillAppear:]
RESetBlock(class, @selector(viewWillAppear:), NO, kBlockKey, ^(UIViewController<RLRAppearanceForwarding> *vc, BOOL animated) {
// supermethod
RESupermethod(nil, vc, animated);
// Forward
if ([vc isAppearanceForwardingEnabled]) {
for (UIViewController *aChildViewController in vc.childViewControllers) {
[aChildViewController beginAppearanceTransition:YES animated:animated];
}
}
});
#pragma mark └ -[class viewDidAppear:]
RESetBlock(class, @selector(viewDidAppear:), NO, kBlockKey, ^(UIViewController<RLRAppearanceForwarding> *vc, BOOL animated) {
// supermethod
RESupermethod(nil, vc, animated);
// Forward
if ([vc isAppearanceForwardingEnabled]) {
[vc.childViewControllers makeObjectsPerformSelector:@selector(endAppearanceTransition)];
}
});
#pragma mark └ -[class viewWillDisappear:]
RESetBlock(class, @selector(viewWillDisappear:), NO, kBlockKey, ^(UIViewController<RLRAppearanceForwarding> *vc, BOOL animated) {
// supermethod
RESupermethod(nil, vc, animated);
// Forward
if ([vc isAppearanceForwardingEnabled]) {
for (UIViewController *aChildViewController in vc.childViewControllers) {
[aChildViewController beginAppearanceTransition:NO animated:animated];
}
}
});
#pragma mark └ -[class viewDidDisappear:]
RESetBlock(class, @selector(viewDidDisappear:), NO, kBlockKey, ^(UIViewController<RLRAppearanceForwarding> *vc, BOOL animated) {
// supermethod
RESupermethod(nil, vc, animated);
// Forward
if ([vc isAppearanceForwardingEnabled]) {
[vc.childViewControllers makeObjectsPerformSelector:@selector(endAppearanceTransition)];
}
});
}
}
}
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment