25

I have an app that work only in Portrait Mode, but there is a singleView that can display video, so i want that view work also in the landscape mode, but in iOS 6 I can't figure out how I can do it, now I have this:

In AppDelegate.m i have:

self.window.rootViewController = myTabBar;

then in the Summary of the project:

enter image description here

and i found that in iOS 6 to detect the view rotation i have to do this:

- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}

// Tell the system It should autorotate
- (BOOL) shouldAutorotate {
return YES;
}

so i insert the code above only in my UIViewController that I want use also in landscape, but don't work, anyone knows how i can do it? i just want the autorotate when show video.

Bartłomiej Semańczyk
  • 59,234
  • 49
  • 233
  • 358
Piero
  • 9,173
  • 18
  • 90
  • 160

3 Answers3

49

Firstly, your target settings should look like this: Supported Interface Orientations

In UITabBarController:

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // You do not need this method if you are not supporting earlier iOS Versions
    return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}

-(NSUInteger)supportedInterfaceOrientations
{
    if (self.selectedViewController) 
        return [self.selectedViewController supportedInterfaceOrientations];

    return UIInterfaceOrientationMaskPortrait;
}

-(BOOL)shouldAutorotate
{
    return YES;
}

Inside your ViewController:

a) if you dont want to rotate:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (BOOL)shouldAutorotate
{
    return NO;
}

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

b) if you want to rotate to landscape:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

- (BOOL)shouldAutorotate
{
    return YES;
}

- (NSInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAllButUpsideDown;
}

Edit:

Other solution is to implement this method inside AppDelegate:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    NSUInteger orientations = UIInterfaceOrientationMaskAll;

    if (self.window.rootViewController) {
        UIViewController* presented = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
        orientations = [presented supportedInterfaceOrientations];
    }
    return orientations; 
}
Michal Zaborowski
  • 5,039
  • 36
  • 35
  • Thanks for your answer, but i can't understand how and where i can write the code for the UITabBarController if i create the UITabBar in this way: UITabBarController *myTabBar = [UITabBarController alloc] init]; and then i set the viewcontrollers for the tabbar, and i do it all in the didfinish method of App Delegate... – Piero Sep 23 '12 at 11:20
  • UITabBar is only some control, you need to tell me on which contrainer you added it, look article from Beppe. – Michal Zaborowski Sep 23 '12 at 11:25
  • Ok in didFinishLaunchingWithOptions in AppDelegate i'll do this:self.window.rootViewController = myTabBar; so i have to do that code in app delegate? – Piero Sep 23 '12 at 11:34
  • Which type is myTabBar ? UITabBarController ? – Michal Zaborowski Sep 23 '12 at 11:35
  • You have to make own subclass of UITabBarController, @interface YourUiTabBarController : UITabBarController – Michal Zaborowski Sep 23 '12 at 14:30
  • @mientus You are not allowed to subclass UITabBarController... From UITabBarController Class Reference: "This class is not intended for subclassing." – Giuseppe Garassino Sep 23 '12 at 16:03
  • Ah i can't sublcass it?...so how i can do it?...i want only display an embed youtube video in fullscreen, and with iOS 6 i can't find a solution, with ios 5 the video start automatically in full screen, but now start in portrait and i want it always only in full screen, any ida? – Piero Sep 23 '12 at 19:04
  • "This class is not intended for subclassing" doesn't mean that you can't do it ... You can do it for things like this... – Michal Zaborowski Sep 23 '12 at 19:12
  • @Beppe http://stackoverflow.com/questions/2377044/overriding-uitabbarcontroller-is-it-safe – Michal Zaborowski Sep 24 '12 at 00:45
  • @mientus Thanks for sharing, but I stick to my idea: I don't risk my neck for nothing... – Giuseppe Garassino Sep 24 '12 at 08:21
  • @Piero You can chose the way you like most, but as long as the view you want to rotate is in fullscreen, you don't need at all to put it in your UITabBarController hierarchy and I recommend to do so. – Giuseppe Garassino Sep 24 '12 at 08:26
  • There is no other solution for iOS6! – Michal Zaborowski Sep 24 '12 at 11:40
  • Hello, again, i have tried yesterday to do what you say, and it's work! rotate only the view i want, but then i delete the code and i start a new project, and i have again write what you say, but now don't work anymore, in ios 5 work, but in iOS 6 rotate every time, also if i put don't rotate, i can't understand why, i have follow what you say step by step, but nothing, yesterday is working and today don't work no more, i have also tried to insert a breakpoint in should autorotate of a uiviewcontroller and don't enter in that method but enter in supportedInterfaceOrientations...any idea? :( – Piero Sep 24 '12 at 21:12
  • 1
    this is the answer: http://stackoverflow.com/questions/12504464/ios-6-uitabbarcontroller-supported-orientation-with-current-uinavigation-control – Piero Sep 24 '12 at 21:38
  • Make a Category instead of a Subclass. – Maverick1st Sep 27 '12 at 08:47
3

I would write a comment but I can't, so I'm posting this as an answer.

This was my scenario :

My app supports orientation changing only on certain views and I couldn't figure out how to do it just for the ones I wanted, then I landed to this question and saw mientus' answer(Thanks for this) then I went ahead and did what he suggested which was subclass UITabBarController and override these methods :

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{

    NSLog(@"AUTO ROTATE IN CUSTOM TAB BAR");
    // You do not need this method if you are not supporting earlier iOS Versions
    return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}


-(NSUInteger)supportedInterfaceOrientations{

    NSLog(@"supportedInterfaceOrientations IN CUSTOM TAB BAR");

    if (self.selectedViewController)
        return [self.selectedViewController supportedInterfaceOrientations];

    return UIInterfaceOrientationMaskPortrait;
}

-(BOOL)shouldAutorotate{

    NSLog(@"shouldAutorotate IN CUSTOM TAB BAR");
    return [self.selectedViewController shouldAutorotate];
}

then inside each view controller I would have the methods to indicate whether I wanted rotation or not. The methods in UITabBarController were getting called but not the ones in my viewcontroller therefore rotation was still happening where I didn't want to. Then I subclass UINavigationController and override the same methods only with this change on the supportedInterfaceOrientation one to look like this :

- (NSUInteger)supportedInterfaceOrientations{

NSLog(@"supportedInterfaceOrientations IN CUSTOM NAV BAR CALLING CURRENT VIEW CONTROLLER");
UIViewController* presented = [[self viewControllers] lastObject];
return [presented supportedInterfaceOrientations];

}

what this does basically, it gets the current view controller and then asks for the supported orientation and voila my methods in my viewcontroller get called and I can handle orientation where I want it.

Bill Burgess
  • 14,054
  • 6
  • 49
  • 86
0

Is the view you want to rotate a subview of portrait-only view? Usually view rotation behaviour inherits from rootviewcontroller. Then if you return NO in shouldAutorotate in rootviewcontroller you stop rotation in every single underview.

I suggest to split your architecture this way:

rootViewController -> supportedInterfaceOrientations = Portrait & shouldAutorotate = YES NORotationViewControllers -> supportedInterfaceOrientations = Portrait & shouldAutorotate = YES rotationViewControllers -> supportedInterfaceOrientations = All & shouldAutorotate = YES

If you have not read this already, take a look at: Supporting Multiple Interface Orientations

Giuseppe Garassino
  • 2,272
  • 1
  • 27
  • 47