Created
September 4, 2012 21:09
-
-
Save tylerstillwater/3626528 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// TBSplitViewController.h | |
// | |
// Created by Tyler Bunnell on 8/4/12 | |
// Released under the have fun with this and make cool stuff license. | |
// | |
#import <UIKit/UIKit.h> | |
@interface TBSplitViewController : UISplitViewController | |
{ | |
id willRotateObserver; | |
id didRotateObserver; | |
} | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// TBSplitViewController.m | |
// | |
// Created by Tyler Bunnell on 8/4/12 | |
// Released under the have fun with this and make cool stuff license. | |
// | |
// This class makes a UISplitViewController respond to orientation changes | |
// properly when it is not in focus. For example, when it is contained in | |
// a UITabBarController and its tab is not selected. | |
// | |
// This code uses ARC and was written for iOS 6+, though it may | |
// work for previous versions. | |
// This code uses valueForKey to access private member variables | |
// in Apple frameworks. This may cause your application to be rejected, | |
// but it is unlikely, as these objects are not being manipulated directly. | |
// Thanks to https://github.com/grgcombs/IntelligentSplitViewController/ for | |
// information used in this code. | |
// | |
#import "TBSplitViewController.h" | |
@interface TBSplitViewController () | |
- (void)addObservers; | |
- (void)removeObservers; | |
- (void)sendSplitViewControllerMessagesForOrientation:(UIInterfaceOrientation)orientation; | |
@end | |
@implementation TBSplitViewController | |
// When the view appears, remove our observers to prevent sending the | |
// rotation and delegate methods twice | |
- (void)viewWillAppear:(BOOL)animated | |
{ | |
[self removeObservers]; | |
[super viewWillAppear:animated]; | |
} | |
// When the view disappears, add our observers so we can be notified of the | |
// rotation changes in the background | |
- (void)viewWillDisappear:(BOOL)animated | |
{ | |
[self addObservers]; | |
[super viewWillDisappear:animated]; | |
} | |
// In the observers below, we send the messages asynchronously and on the main thread. | |
// If we don't, there are problems with the master view not being visible once we | |
// switch back to the split view after having rotated in the background. | |
- (void)addObservers | |
{ | |
willRotateObserver = | |
[[NSNotificationCenter defaultCenter] | |
addObserverForName:UIApplicationWillChangeStatusBarOrientationNotification | |
object:nil | |
queue:nil | |
usingBlock:^(NSNotification *notification) { | |
UIInterfaceOrientation toOrientation = [[[notification userInfo] valueForKey:UIApplicationStatusBarOrientationUserInfoKey] integerValue]; | |
NSTimeInterval duration = [[UIApplication sharedApplication] statusBarOrientationAnimationDuration]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
[self willRotateToInterfaceOrientation:toOrientation duration:duration]; | |
[self sendSplitViewControllerMessagesForOrientation:toOrientation]; | |
}); | |
}]; | |
didRotateObserver = | |
[[NSNotificationCenter defaultCenter] | |
addObserverForName:UIApplicationWillChangeStatusBarOrientationNotification | |
object:nil | |
queue:nil | |
usingBlock:^(NSNotification *notification) { | |
UIInterfaceOrientation fromOrientation = [[[notification userInfo] valueForKey:UIApplicationStatusBarOrientationUserInfoKey] integerValue]; | |
dispatch_async(dispatch_get_main_queue(),^{ | |
[self didRotateFromInterfaceOrientation:fromOrientation]; | |
}); | |
}]; | |
} | |
- (void)removeObservers | |
{ | |
[[NSNotificationCenter defaultCenter] removeObserver:willRotateObserver]; | |
willRotateObserver = nil; | |
[[NSNotificationCenter defaultCenter] removeObserver:didRotateObserver]; | |
didRotateObserver = nil; | |
} | |
- (BOOL)shouldAutorotate | |
{ | |
return YES; | |
} | |
- (void)sendSplitViewControllerMessagesForOrientation:(UIInterfaceOrientation)orientation; | |
{ | |
id delegate = [self delegate]; | |
UIViewController* masterViewController = [[self viewControllers] objectAtIndex:0]; | |
UIBarButtonItem* barButtonItem = [super valueForKey:@"_barButtonItem"]; | |
// Here, we send the delegate messages as are appropriate for what is happening. | |
if(UIInterfaceOrientationIsPortrait(orientation)) | |
{ | |
if([delegate respondsToSelector:@selector(splitViewController:willHideViewController:withBarButtonItem:forPopoverController:)]) | |
{ | |
UIPopoverController* popoverController = [super valueForKey:@"_hiddenPopoverController"]; | |
[delegate splitViewController:self willHideViewController:masterViewController withBarButtonItem:barButtonItem forPopoverController:popoverController]; | |
} | |
} | |
else if(UIInterfaceOrientationIsLandscape(orientation)) | |
{ | |
if([delegate respondsToSelector:@selector(splitViewController:willShowViewController:invalidatingBarButtonItem:)]) | |
{ | |
[delegate splitViewController:self willShowViewController:masterViewController invalidatingBarButtonItem:barButtonItem]; | |
} | |
} | |
else | |
{ | |
[NSException raise:@"TBUnknownOrientationException" format:@"TBSplitViewController is attempting to rotate to an unknown orientation."]; | |
} | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment