Hi I have an Tab Bar based application. When I click on the third tab,the view which opens up has a tableview (AggregateMediaViewController). On didSelect of the rows, I open a video using MPMoviePlayerViewController. I want to set the the orientation of the this video whenever the orientation of the device changes.
I created a subclass of UITabbarController called OrientationTabBarController:
#implementation OrientationTabBarControllerViewController
- (BOOL)shouldAutorotate {
NSLog(#"in shouldAutorotate tabbar is %#", self.viewControllers);
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
In the appDidFifnishLaunching:
[window setRootViewController:tabBarController];
where the tabBarController is a subclass of OrientationTabBarController.
In AggregateMediaViewController, I have the following code:
- (BOOL)shouldAutorotate
{
NSLog(#"in shouldAutorotate of media");
return YES;
}
-(NSInteger)supportedInterfaceOrientations {
return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortraitUpsideDown);
}
But when I run the application, orientation does not work :( Please Help
You need to subclass your parent controller and add rotation methods of your UIViewController. In your case it is UITabBarController. And set it as rootViewController in appDelegate:
[self.window setRootViewController:_myTabBarController];
Related
I am trying to create a custom segue to change and lock my next view into portrait mode, no matter how the device is rotated. I was able to create my UIStoryBoardSegue files, but now I am stuck with the code to switch from landscape to portrait... this is what I did so far:
-(void) perform
{
self.appDelegate = [[UIApplication sharedApplication] delegate];
UIViewController *source = (UIViewController *) self.sourceViewController;
UIViewController *destination = (UIViewController *) self.destinationViewController;
}
And now I am stuck... help!
I don't know if you are writting for iOS 6 or per iOS 6, but if it is iOS 6, try placing the following code in the view controller that you are trying to set its orientation.
- (BOOL) shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}
Now the method above has all the masks and you can remove the masks you don't need. There is really no need to access the app delegate for rotation setting any more. Hope this helps you achieve what you want.
One way is to overload the supportedDeviceOrientations method of a view controller subclass like this
- (NSUInteger)supportedInterfaceOrientations {
return UIDeviceOrientationPortrait;
}
In my app, Four viewcontrollers navigates next by next in potrait mode, but i added coverflow in the final viewcontroller, and when the simulator is rotated it should go landscape.I selected all orientations in plist execpt the Upsidedown orientation, So that coverflow works fine in Landscape, but all the other viewcontrollers also goes to landscape when rotatad, but i need these viewcontrollers to be in potrait even the simulator is rotated.I tried many codes like,
shouldAutorotate and supportedInterfaceOrientations.
But i doesn't get a clear solution towards what iam expecting, if any ideas , will be thankfull.
Add an observer to the viewDidLoad method of the view you want to rotate like this :
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:[UIDevice currentDevice]];
and then set the views according the the landscape view inside the orientationChanged method like this :
- (void) orientationChanged:(NSNotification *)note{
UIDevice * device = [UIDevice currentDevice];
switch(device.orientation)
{
case UIDeviceOrientationPortrait:
break;
case UIDeviceOrientationPortraitUpsideDown:
break;
case UIDeviceOrientationLandscapeLeft:
break;
case UIDeviceOrientationLandscapeRight:
break;
default:
break;
};
}
Add new Objective-C class (subclass of UINavigationController) and add the following code to the .m files
-(NSUInteger)supportedInterfaceOrientations
{
NSLog(#"supportedInterfaceOrientations = %d ", [self.topViewController supportedInterfaceOrientations]);
return [self.topViewController supportedInterfaceOrientations];
}
-(BOOL)shouldAutorotate
{
return self.topViewController.shouldAutorotate;
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// You do not need this method if you are not supporting earlier iOS Versions
return [self.topViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
After you added the new classes go to your ViewController classes and make the following changes
- (BOOL)shouldAutorotate // iOS 6 autorotation fix
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations // iOS 6 autorotation fix
{
return UIInterfaceOrientationMaskAll;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation // iOS 6 autorotation fix
{
return UIInterfaceOrientationPortrait;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return YES;
}
In the shouldAutorotate , shouldAutorotateToInterfaceOrientation: return YES if you want the ViewController to be supporting Multiple orientation else return NO , also in houldAutorotateToInterfaceOrientation: method pass the Orintation you want for that specific ViewController , Repeat the same for all the view controllers .
Reason of doing this:-
1:Although you can change the preferredInterfaceOrientationForPresentation: of any viewController to a specific orientation but since you are using the UINavigationController you also need to override the supportedInterfaceOrientations for your UINavigationController
2:In order the override the supportedInterfaceOrientations for UINavigationController we have subclassed UINavigationController and modified the method related to the UINavigation Orientation.
Hope it will help you !
In iOS 6 and later, the view controllers responsible for rotation are the container Viewcontrollers such as UINavigationController & UITabBarController . What are you using as the rootviewcontroller in your project??
I have navigation controller category written here in which you can handle the supported interface orientations for the individual view controllers.
viewDidLoad or viewWillApper method add following code
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:YES];
set the orientation
#if (__IPHONE_6_0 >= __IPHONE_OS_VERSION_MAX_ALLOWED)
- (NSInteger)supportedInterfaceOrientations {
return (UIInterfaceOrientationMaskPortraitUpsideDown | UIInterfaceOrientationMaskPortrait);
}
#endif
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation==UIInterfaceOrientationPortrait);
}
I have UITableViewController in which on one tab is UINavigationViewController. UINavigationController root view controller is UITableViewController, and when clicked on cell, UIViewController appears which has to be locked in Landscape.
I want every Controller to be locked in Portrait, except the mentioned UIViewController that must be locked in Portrait.
I have tried the following:
CustomTabBarController.m:
#import "CustomTabBarController.h"
#implementation CustomTabBarController
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// You do not need this method if you are not supporting earlier iOS Versions
return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
- (BOOL)shouldAutorotate{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations{
return [self.selectedViewController supportedInterfaceOrientations];
}
#end
CustomNavigationController.h:
#import "CustomNavigationController.h"
#implementation CustomNavigationController
-(NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
-(BOOL)shouldAutorotate
{
return YES;
}
#end
And in UIViewController that must be locked in to Landscape, I have put:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return ((interfaceOrientation == UIInterfaceOrientationLandscapeLeft) || (interfaceOrientation == UIInterfaceOrientationLandscapeRight));
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
-(BOOL)shouldAutorotate
{
return YES;
}
But it doesn't work, I can rotate it to Landscape and it will stay locked in Landscape, but I want it to appear automatically in Landscape.
Any suggestions?
I had a big problem in the past with UITabBarController not respecting my supported interface orientations of displayed view controllers.
I solved the problem by sub-classing UITabBarController and capturing whenever an item was selected. I'd then call down to the view controller myself, ask it what the supported orientations are and force a rotation myself if needed. I would also call down to the selected view controller on rotations to set/change my supported orientations.
I implemented the UITabBarDelegate and used didSelectItem to capture tab switches. I'm not sure if there is a better way to do it now.
Try to override method
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
Try with the method to block some orientations for a particular window:
– application:supportedInterfaceOrientationsForWindow:
I have UINavigationController with couple of view controller.
this is the list of them:
Main -> Album -> image
Now in the first and the second(Main and album) i want that the UINavigationController will not rotate(only portrait), and in the third one(Image) it will be possible to rotate.
i made already category for the UINavigationController:
-(BOOL)shouldAutorotate {
if ([self.topViewController isKindOfClass:[MWPhotoBrowser class]]) {
return YES;
}
return NO;
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
if ([self.topViewController isKindOfClass:[MWPhotoBrowser class]]) {
return YES;
}
return NO;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}
Now my problem is that when i push the image viewcontroller and the rotate the device (the viewcontroller rotate) and press back and here(Album) the viewcontroller is rotate to and can't rotate back to portrait.
By the way: i noticed it happen only in device with iOS 6 and iPhone 5
Have you tried including the method below but returning the correct value for your view controller?
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortraitUpsideDown;
}
I've got an app where I have a UINavigationController subclass as my rootViewController. I've got a UITableViewController that lets the user edit some settings, it should always be in portrait mode. My app also needs to support all other orientations after I push a MoviePlayer component onto the navigation controller.
The UITableViewController subclass has this implementation of supportedInterfaceOrientations:
- (NSUInteger)supportedInterfaceOrientations {
LLog();
return UIInterfaceOrientationMaskPortrait;
}
The logging command tells me that this gets actually called.
The problem is that the return value is not respected, i.e. the screen turns to landscape orientation when I turn the device.
What can I do to make the settings view always show in portrait but allow orientation changes for the video viewer?
More information: my UINavigationController subclass doesn't override shouldAutorotate or supportedInterfaceOrientations. I haven't implemented
- (NSUInteger)application:(UIApplication *)application
supportedInterfaceOrientationsForWindow:(UIWindow *)window
method in my AppDelegate and I have enabled all orientations in the target summary.
I had issue that some ViewControllers in the navigation stack support all the orientations, some only portrait, but UINavigation controller was returning all app supported orientations, this little hack helped me.
#implementation UINavigationController (iOS6OrientationFix)
-(NSUInteger) supportedInterfaceOrientations {
return [self.topViewController supportedInterfaceOrientations];
}
#end
You also need to add:
- (BOOL)shouldAutorotate {
return NO;
}
and set the supported rotations for the root view controller in the app plist file to only portrait.
Category for UINavigationController not working for me. I don't know why. I solve my problem with such category of UIViewController:
#implementation UIViewController (Orientation)
- (BOOL) shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
NSUInteger orientations = UIInterfaceOrientationMaskPortrait;
if ([self isKindOfClass:[PlayerViewController class]])
{
orientations |= UIInterfaceOrientationMaskLandscapeLeft;
orientations |= UIInterfaceOrientationMaskLandscapeRight;
}
return orientations;
}
#end