Skip to content

Instantly share code, notes, and snippets.

@tylerstillwater
Created September 4, 2012 21:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tylerstillwater/3626528 to your computer and use it in GitHub Desktop.
Save tylerstillwater/3626528 to your computer and use it in GitHub Desktop.
//
// 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
//
// 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