Skip to content

Instantly share code, notes, and snippets.

@spoletto
Created September 14, 2012 21:47
Show Gist options
  • Star 22 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save spoletto/3725118 to your computer and use it in GitHub Desktop.
Save spoletto/3725118 to your computer and use it in GitHub Desktop.
iOS 6 Autorotation Swizzling
@implementation AppDelegate
void SwapMethodImplementations(Class cls, SEL left_sel, SEL right_sel) {
Method leftMethod = class_getInstanceMethod(cls, left_sel);
Method rightMethod = class_getInstanceMethod(cls, right_sel);
method_exchangeImplementations(leftMethod, rightMethod);
}
+ (void)initialize {
if (self == [AppDelegate class]) {
#ifdef __IPHONE_6_0
SwapMethodImplementations([UIViewController class], @selector(supportedInterfaceOrientations), @selector(sp_supportedInterfaceOrientations));
SwapMethodImplementations([UIViewController class], @selector(shouldAutorotate), @selector(sp_shouldAutorotate));
#endif
}
}
@end
@implementation UIViewController (iOS6Autorotation)
#ifdef __IPHONE_6_0
/*
* We've swizzled the new iOS 6 autorotation callbacks onto their iOS 5 and iOS 4 equivalents
* to preserve existing functionality.
*
*/
- (BOOL)sp_shouldAutorotate {
BOOL shouldAutorotate = YES;
if ([self respondsToSelector:@selector(shouldAutorotateToInterfaceOrientation:)]) {
NSUInteger mask = 0;
if ([self shouldAutorotateToInterfaceOrientation:UIInterfaceOrientationPortrait]) {
mask |= UIInterfaceOrientationMaskPortrait;
}
if ([self shouldAutorotateToInterfaceOrientation:UIInterfaceOrientationLandscapeLeft]) {
mask |= UIInterfaceOrientationMaskLandscapeLeft;
}
if ([self shouldAutorotateToInterfaceOrientation:UIInterfaceOrientationLandscapeRight]) {
mask |= UIInterfaceOrientationMaskLandscapeRight;
}
if ([self shouldAutorotateToInterfaceOrientation:UIInterfaceOrientationPortraitUpsideDown]) {
mask |= UIInterfaceOrientationMaskPortraitUpsideDown;
}
if (mask == 0) {
// Shouldn't autorotate to *any* orientation.
shouldAutorotate = NO;
}
} else {
// This actually calls the original method implementation
// instead of recursively calling into this method implementation.
shouldAutorotate = [self sp_shouldAutorotate];
}
return shouldAutorotate;
}
- (NSUInteger)sp_supportedInterfaceOrientations {
NSUInteger mask = 0;
/*
* In iOS 6, Apple dramatically changed the way autorotation works.
* Rather than having each view controller respond to shouldAutorotateToInterfaceOrientation:
* to specify whether or not it could support a particular orientation, the responsibility was
* shifted to top-level container view controllers. That means UINavigationController becomes
* responsible for declaring whether or not an orientation is supported. Since our app
* has logic for how to autorotate on a per view controller basis, we call through to the
* swizzled version of supportedInterfaceOrientations for the topViewController.
*
*/
if ([self isKindOfClass:[UINavigationController class]]) {
return [[(UINavigationController *)self topViewController] supportedInterfaceOrientations];
}
if ([self respondsToSelector:@selector(shouldAutorotateToInterfaceOrientation:)]) {
if ([self shouldAutorotateToInterfaceOrientation:UIInterfaceOrientationPortrait]) {
mask |= UIInterfaceOrientationMaskPortrait;
}
if ([self shouldAutorotateToInterfaceOrientation:UIInterfaceOrientationLandscapeLeft]) {
mask |= UIInterfaceOrientationMaskLandscapeLeft;
}
if ([self shouldAutorotateToInterfaceOrientation:UIInterfaceOrientationLandscapeRight]) {
mask |= UIInterfaceOrientationMaskLandscapeRight;
}
if ([self shouldAutorotateToInterfaceOrientation:UIInterfaceOrientationPortraitUpsideDown]) {
mask |= UIInterfaceOrientationMaskPortraitUpsideDown;
}
} else {
// This actually calls the original method implementation
// instead of recursively calling into this method implementation.
mask = [self sp_supportedInterfaceOrientations];
}
return mask;
}
#endif
@end
@haikusw
Copy link

haikusw commented Sep 20, 2012

as @davedelong said on twitter: "I love the runtime as much (or more) than the next guy, but you should absolutely not use [this] code."

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