UITabBarController and rotation iOS6 - ipad

Happy Memorial Day for those in America!
I am new to iOS and Objective-C programming; a few weeks ago I inherited an iPad app-in-development that was being designed for iOS 5. I now have everything working except the rotation in iOS 6. I know that iPad apps should rotate to every orientation be default (which is what I want), yet mine does not. Everything rotates perfectly in iOS 5, and I can get my splash screen to rotate perfectly in iOS 6, but that is all. I cannot get the activities (once you click through the splash screen) to rotate properly.
I have searched stackoverflow and other websites to figure out what I must do, so I know to implement -(BOOL)shouldAutorotate and -(NSUInteger)supportedInterfaceOrientations in any specific ViewController to control that view's orientation behavior. I've read that having that different rotation behavior in one VC can affect the entire app. So I made sure that every VC that I could find** would now implement those two iOS 6 methods to return YES and UIInterfaceOrientationMaskAll, respectively. That didn't work. I read about returning self.tabBarController.shouldAutorotate and self.tabBarController.supportedInterfaceOrientations in those methods to ensure that the tabbar rotation behavior is consistent, but that didn't work. I have read about implementing a category (UITabBarController+autoRotate.m and .h) that implements these two methods, and that didn't work. I have read about subclassing the tabBarController, and I think my code does that: in my appDelegate, I call
[myWindow setRootViewController:activityViewController],
where activityViewController is an instance of class BicycleFamilyAcitivityViewController, which is from
#interface BicycleFamilyActivityViewController : UIViewController <UITabBarControllerDelegate>
When I investigate what is being called during the successful splash screen rotation using the iOS 6 simulator, I notice that those two implemented methods in BicycleFamilyAcitivityViewController are being called (twice each, actually) and that -(void)willAnimateRotationToInterfaceOrientation:duration is as well. When I try to rotate while viewing an activity (after clicking through the splash screen), those two methods are only called once, and -(void)willAnimateRotationToInterfaceOrientation:duration is not called. In both instances, the appDelegate's -(NSUInteger)application:supportedInterfaceOrientationsForWindow method is called.
Any advice on how to get rotation to work throughout the entire app? Even if it's just pointing to an answer on StackOverflow that I haven't yet seen (or fully understood), I would be most grateful.
Many thanks in advance!
Bernie
** In looking for VC classes in the project, I made sure to consider any class that implemented the rotation method of iOS 5: -(BOOL)shouldAutorotateToInterfaceOrientation:interfaceOrientation

In iOS 6 the Orientation functions have changed. Your set up should look like this in your viewControllers:
-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationLandscapeRight;
}
-(BOOL)shouldAutorotate {
return TRUE;
}
UIInterfaceOrientationMaskAll is all orientations, more information here.

Someone in-house figured out the problem. I thought I would post the answer to help anyone who has a similar predicament.
What I had tried (among other things) was: setting the UIWindow in my appDelegate class to be my instance of a subclass (BicycleFamilyAcitivityViewController) of UIViewController. In my appDelegate, I had:
[myWindow setRootViewController:activityViewController];
where activityViewController is an instance of a subclass of UIViewController.
But I should have created an additional UIWindow via delegate, then assign the TabBarController (tbc) as it's root VC when I build my TabBarController. In my primary view controller class, I had a buildTabBarController function. So these two lines in that function allowed my rotation to work:
UIWindow *keyWindow = [[[UIApplication sharedApplication] delegate] window];
[keyWindow setRootViewController:tbc];
Hope this helps!

Related

Can't restrict UIViewController to Portrait only

I'm embedding my app in a UINavigationController, I want most of myViewControllers except one to be Portrait, I've read a lot of questions but could not find a correct answer that works for me.
In my target I'm selecting Device Orientation : Portrait, Landscape Right
I'm adding this to my first ViewController:
-(BOOL)shouldAutorotate{
return NO;
}
-(NSUInteger)supportedInterfaceOrientations{
return (UIInterfaceOrientationPortrait);
}
But when I rotate the device left the ViewController rotates as well.
Why is it rotating?
You can't easily do in iOS 7 what you're describing. A UINavigationController does not consult its children as to what rotations they like; whatever the permitted rotations of the UINavigationController, those are the permitted rotations of the app, regardless of which child happens to be showing at that moment.
The only really legal and built-in way to force rotation is to use a presented ("modal") view controller that takes over the screen. Its rotation settings are consulted because it is now in charge of the screen.

iOS >> Device Orientation >> Screen is Not Supporting Upside Down

I have a screen that supports Device Orientation.
Everything is working fine except for the fact that when I rotate the device upside down (home button at top), the rotation doesn't work (it's stuck on the last landscape settings).
I know of several places needed be updated to support this:
In the VC itself, I added the methods:
In the Project Target, I updated as follow:
In the Storyboard VC Scene, I updated as follow:
What am I missing here?
You also have to allow rotating to all orientations in every parent view controller of the current main view controller. For example, if your view controller is in navigation controller, try subclassing it and override the same methods as in your example.
Edit: As #JordanC mentioned, since iOS 7 you can implement UINavigationControllerDelegate method to return custom supported orientations:
- (UIInterfaceOrientationMask)navigationControllerSupportedInterfaceOrientations:(UINavigationController *)navigationController
As #eGanges mentioned the key point could be to subclass your UITabBarController (and override supportedInterfaceOrientations) if that is your initial view controller, in that case this is the only controller you should subclass (and of course you should add all the supported interface orientations to your app Info.plist file UISupportedInterfaceOrientations key)
Have you tested on real device?
anyway try this:
- (NSUInteger)supportedInterfaceOrientations {
return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
}

UITabBarController/UINavigationController rotation issues

My problem is the following: I want to only allow Portrait orientation on all my ViewControllers except 1 ViewController which is supposed to allow both Portrait and landscapeLeft/Right. I have now spent almost 2 days into how to set orientation in IOS for different slides/ViewControllers. After some searching I found this thread here at stack: UITabBarController Rotation Issues in ios 6
I followed Kunani's example in that thread which I will post here to save all readers some time:
Zack, I ran into this same issue. It's because you have your viewController embedded inside of a TabBar Controller or UINavigationController and the calls to these methods are happening inside those instead of your normal View (Changed in iOS6). I ran into this issue because I was presenting a viewController embedded inside a UINavigationController on all my modal views that had Navigation to different views (Signup Process, Login, etc). My simple fix was to create a CATEGORY for UINavigationController that includes these two methods. I have shouldAutorotate returning NO anyway because I don't want my modal views rotating. Your fix may be this simple, give it a try. Hope it helps. I created a category and named it autoRotate and selected theUINavigationController option. The M+H file are below.
#import "UINavigationController+autoRotate.h"
#implementation UINavigationController (autoRotate)
-(BOOL)shouldAutorotate {
return NO;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
#end
... and the category .h:
#import <UIKit/UIKit.h>
#interface UINavigationController (autoRotate)
-(BOOL)shouldAutorotate;
- (NSUInteger)supportedInterfaceOrientations;
#end
I did what he said and tried to set category for my UITabBarController which worked, all classes connected to the tabBar now only allows orientationPortrait. But if you look at the following Picture
(screenshot from my project) there is a class in the middle of the StoryBoard called ShowTaskView. This class is connected to most classes (which are directly connected to the UITabBarController) via a UINavigationController. Even if I set UITabBarController to only allow Portrait also ShowTaskView seems to get affected by that rule and I can not make it to rotate. The scheme in my project can also be described as this:
TabBarController ----> UINavigationController -------> class X ----------> class ShowTaskView
What can I do from here if I want my classes connected to tabBarController only to allow orientationPortrait and the rest of the classes allow both portrait and landscape based on how my project is built? I am very frustrated at this issue since it is so damn hard to solve :/
Regards
please refer to my answer in similar thread: Navigation controller stack in landscape mode, but modally presented view controller view always in portrait frame size
iOS6 controls rotation by the navigation stacks, so wrap your rotatable view into separate navigation controller to be able to control it there.

iPad Landscape not resizing SubViews correctly

I am writing an iPad application using MonoTouch, MonoDevelop and Interface Builder, and i've stumbled across a problem that I can't seem to solve. It is probably something simple. What I am trying to do is force an application to Landscapemode from start. The application starts in Landscape, but doesn't resize the subviews correctly.
Basically what I am doing in my appdelegate is that I add a SubView called IndexViewController.xib to Window. In IndexViewController I have a View with a Label on it, if I then in IndexViewController override the ShouldAutorotateToInterfaceOrientation to return this: it works correctly.
public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation)
{
return ((toInterfaceOrientation == UIInterfaceOrientation.LandscapeLeft) || (toInterfaceOrientation == UIInterfaceOrientation.LandscapeRight));
}
However, I now try to create a NavigationController and add it to the IndexController.xib-view on the Initialize:
void Initialize ()
{
this.View.AddSubview (NavController.View);
}
It rotates correctly but doesn't fill the entire "window", I have posted a screenshot and a sample solution. And my info.plist is set to allow "UIInterfaceOrientationLandscapeLeft" and "UIInterfaceOrientationLandscapeLeftRight" as UISupportedInterfaceOrientations
Screenshot
Sample solution here
There is probably something dead simple simple that I am missing, but I can't figure it out.
I'd say this may be due to the fact the way you're building the app's hierarchy isn't the suggested way of doing so. While you could carry on this way, you'll encounter more problems down the road.
Ideally you want to be adding the NavigationController's View the window rather than the having the NavigationController contained within a UIViewController.
In the app delegate, I would do something along the lines of:
IndexViewController indexVC = new IndexViewController()
UINavigationController navController = new UINavigationController(indexVC);
window.AddSubview(navController.View);
This will add the navigation controller's view to the window, with the RootViewController of the NavigationController being your IndexViewController
You should also remove the UINavigationController that is added to your IndexViewController in Initialise().
I just downloaded your sample solution and tried this very quickly and it loaded the app in Landscape with the view fully filling the screen. It didn't auto rotate, but this'll certainly be a good starting point for you :)

Adding UIViewController.view to another view causes orientation problems

Short version:
I'm alloc/init/retaining a new UIViewController in one UIViewControllers viewDidLoad method, adding the new View to self.view. This usually works, but it seems to mess up orientation change handling of my iPad app.
Longer version:
I'm building a fairly complex iPad application, involving a lot of views and viewcontrollers. After running into some difficulties adjusting to the device orientation, I made a simple XCode project to figure out what the problem is.
Firstly, I have read the Apple Docs on this subject (a small document called "Why won't my UIViewController rotate with the device?"), and while I do believe it has something to do with one of the reasons listed there, I'm not really sure how to fix it.
In my test project I have an appDelegate, a rootViewController, and a UISplitViewController with two custom viewControllers. I use a button on the rootViewController to switch to the splitViewController, and from there I can use a button to switch back to the rootViewController. So far everything is great, i.e. all views adjust to the device orientation.
However, in the right viewController of the splitViewController, I use the viewDidLoad method to initialize some other viewControllers, and add their views to its own view:
self.newViewController = [[UIViewController new] autorelease];
[newViewController.view setBackgroundColor:[UIColor yellowColor]];
[self.view addSubview:newViewController.view];
This is where things go wrong. Somehow, after adding this view, adjusting to device orientation is messy. On startup everything is fine, after I switch to the splitViewController everything is still fine, but as soon as I switch back to the rootViewController it's all over. I have tried (almost) everything regarding retaining and releasing the viewcontroller, but nothing seems to fix it.
As you can see from the code above, I have declared the newViewController as a property, but the same happens if I don't.
Shouldn't I be adding a ViewController's view to my own view at all? That would really mess up my project, as I have a lot of viewControllers doing all sorts of things.
Any help on this would be greatly appreciated...
I had the same problem, seams resolved by removing from the parent view the "autoresize subview" option in IB.
Select the view a then: Inspector -> Attributes (first tab) -> drawing.
What I think is happening is that your new viewcontroller is getting the autorotation calls and probably not handling them. Meanwhile your old viewcontrollers and its views won't get the autorotation calls and will be stuck in whatever orientation they were in.
I can't tell, but I think what you want to do is to make a UIView and add it to your old viewcontroller, instead of making a UIVIewController and adding its view.

Resources