Fix Status Bar even in Landscape - objective-c

I have a ViewController inside a UINavigationController and only this navigationController in my app is in portrait. So i forced it to be
always in portrait implementing in my NavigationController the following methods:
(UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
(BOOL) shouldAutorotate {
return NO;
}
So it works to force my NavigationController be always in portrait programmatically. But when a change to landscape in simulator my status bar disappear. I want to keep my status bar appearing in portrait mode even if i change it to landscape ( its not a landscape at all, it is a rotation ).
I've tried a lot of things with no result.
Thanks

Related

How to setting orientation for each ViewController in Tabbed Application in iOS7?

In the Tabbed Application I have two View.
I want to fix the firstView to portrait and the seccondView can rotate to portrait and landscape.
I implement the code below in firstViewController.
- (NSUInteger)supportedInterfaceOrientation {
return UIInterfaceOrientationMaskPortrait;
}
The code in secondViewController is
- (NSUInteger)supportedInterfaceOrientation {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
But when I rotate my phone, the setting have no working.
Cloud somebody can tell my how to do that.
You need to subclass your UINavigationController and UITabBarController. Take a look at this questions, it is essentially the same shouldAutorotate, supportedInterfaceOrientations and preferredInterfaceOrientationForPresentation does not work as expected in iOS 7

Fixed orientation for a view controller

In my app I've a UITabBarController that contains 3 UINavigationController. I can freeze orientation for any UIViewController. For this I've implemented UITabBarController and UINavigationController. But problem occurs when I push a UIViewController from another one that was in Landscape. The newly pushed UIViewController should be in portrait but it remains in Landscape. I know problem may be unclear so I am attaching scrrenshots.
Lets consider its VC-A.
Pressing edit from VC-A goes to this VC-B. VC-B is:
This VC-B should always in portrait. VC-A can be in Landscape or portrait. When VC-A is in landscape and I press edit the VC-B is pushed and VC-B comes in landscape mode though I implemented these methods in VC-B:
-(BOOL)shouldAutorotate {
return UIInterfaceOrientationMaskPortrait;
}
-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationPortrait;
}
Your shouldAutorotate needs to return a BOOL not the mask, so code should be
-(BOOL)shouldAutorotate {
return YES;
}
All child view controllers in a tab bar controller or navigation controller must have the same set of supported orientations. This is discussed near the bottom of the following document.
https://developer.apple.com/library/ios/qa/qa1688/_index.html

launching a modal view controller to work around the orientation "lock" of tab bar and nav VCs?

I have an iPhone app with a root view controller (VC) of UITabBarController (set to portrait orientation) with several tabs, one of which is a simple UIViewController. In that UIViewController is a single button - "Play Video", which, when clicked opens a modal view of the video (and automatically starts playing the video). The video view is a UIWebView in a UIViewController. I've been trying to get the Web View's VC to change orientation to landscape but have not had any luck.
I've looked around and understand that if you have a Tab Bar or a Nav controller, all children VCs will be the same orientation as the parent - makes sense. This is why I made the web view's VC modal, hoping this is a way around the orientation issue.
My question is: is this accurate - that using modal will not require the web view VC to be portrait and can respond to the shouldAutorotateToInterfaceOrientation method (even though I have not yet been able to get it to work)?
BTW, using iOS 6.
Thanks in advance.
Apparently in ios6 and above, the way rotation works is different. So what you have to do is the following
In your .plist support all 4 orientations.
Subclass the UITabBarController (for e.g: CustomTabBarController)
In the CustomTabBarController put the following lines of code
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
In your app delegate or where ever you are initializing UITabBarController, replace those instances with CustomTabBarController instances.
In your modal controller put the lines
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeLeft;
}
-(BOOL)shouldAutorotate{
return NO;
}
And it should all work.
Apparently the trick, I found is that, UITabBarController will not listen to your instructions. It will support all the orientations you mention in the .plist.
There fore you have to subclass it.
I tried doing all of the above and it works fine. Do let me know and I can send you the code if you want.
Try this. Just have portrait set in the summary screen, then in the app delegate, implement this:
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
return UIInterfaceOrientationMaskAll;
}
In the tab bar controller (and no other rotation code):
-(BOOL)shouldAutorotate {
return NO;
}
And finally, in the modal view controller:
-(BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}

iOS 6 UIInterfacePortrait ONLY viewcontroller being presented & stuck in landscape... when coming back from a landscape viewcontroller in nav stack

So like many others, I ran into the problem of only having one or two viewcontrollers support both portrait and landscape interface orientations, in an otherwise portrait only app. Everything worked fine prior to iOS 6, but suddenly autorotating stopped working. Thanks to some great questions here, I was able to resolve that issue by having the initial navController return the individual topViewController's preference for shouldAutorotate via:
- (BOOL)shouldAutorotate
{
return self.topViewController.shouldAutorotate;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
However, I have stumbled onto a new problem. the root vc (viewController A) should NOT autorotate and should only support portrait. ViewController B in the nav stack supports portrait and landscape. If I am in viewController B, and am in landscape, and touch "back" to pop the view back to viewController A... vc A loads in landscape, which it is not supposed to even support, and wont rotate back to portrait because shouldAutorotate for vc A is set to NO...
Any ideas on how to deal with this would be greatly appreciated. My initial thought was to override vc B's "back" button with a manual method that first force rotates back to portrait if the view is in landscape... then pops the viewcontroller back to vc A... but I cant figure out how to force a rotation programatically. Any ideas?
here are the interface methods in vc A:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return NO;
}
-(BOOL)shouldAutorotate
{
return NO;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationPortrait;
}
and here is what they are in vc B:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAllButUpsideDown;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationPortrait;
}
In vcA set
-(BOOL)shouldAutorotate
{
return YES;
}
But keep
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationPortrait;
}
Then the view will rotate back to the (only) supported orientation when you return from vcB
The problem is that all container view controllers (Tab Bar Controller, Navigation Controller etc.) support all those interface orientations that you give in your plist file. When the system asks for the supported interface orientations the root view controller's settings and method implementations override it's children's.
In this case the Navigation Controller supports both landscape and portrait and when the B View controller pops, although the system asks for A's interface orientations, it will ask it's root view controller too and that will be the "winner" and since the Navigation Controller supports landscape, it stays in landscape despite that A supports portrait only.
One solution is, that you subclass the root view controller and change it's rotation methods dynamically as needed. When only portait is needed your root's implementation should return portait only and when both orientations are available, then your root should return both.

Interface Orientation won't change to Landscape on App Launch

i stuck on a problem that drives me crazy!
I have an iPad application starting with a TabBarViewController. Every Tab has it's own ViewController and nib-file.
To make interface orientation possible I added all orientations to my info.plist and subclassing my TabBarController to set:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
Every View is autoresized and formatted well for displaying the right Orientation if I rotate the Interface. If I test it in the simulator, everything looks fine and I can rotate between the Orientations.
Now the point that drives me crazy:
If I launch the App in Portrait Mode, all works fine.. but if I launch in Landscape, I get an error and my Interface orientation seems still to be Portrait, while the Simulator is in Landscape Mode!!
The Error:
2011-05-24 21:50:15.011 Project[57995:207] Using two-stage rotation animation. To use the smoother single-stage animation, this application must remove two-stage method implementations.
I checked for Orientation like this:
-(void)viewWillAppear:(BOOL)animated{
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if ((orientation == UIInterfaceOrientationLandscapeLeft) || (orientation == UIInterfaceOrientationLandscapeRight)) {
NSLog(#"Orientation: Landscape");
}
else{
NSLog(#"Orientation: Portrait");
}
}
The Log says it is in "Landscape" Mode if I launch in Landscape, but if I change tab to another it looks terrible because the View is displayed in Portrait mode instead.
On change back to the start-view where i asked for Orientation… the log displays "Portrait"… but the Simulator is still Landscape!
I can't figure out why the Orientation is Portrait on start,…
even if I start in Landscape…
Any idea how to solve this problem?
Ok. So the documentation says viewWillAppear: is called prior to all animations. And when your app starts, its initial orientation is Portrait. Based on what your orientation is, it then rotates to that orientation. Since it animates to the orientation off screen, this must be called after viewWillAppear:/ So when viewWillAppear: is called, its still in Portrait. I tested this myself.
I solved the problem!
Simply used this in viewWillAppear method of all my Views, to make it work when started in Landscape mode:
if(([[UIApplication sharedApplication]statusBarOrientation] == UIInterfaceOrientationLandscapeLeft) || ([[UIApplication sharedApplication]statusBarOrientation] == UIInterfaceOrientationLandscapeRight)){
//Landscape View
}
else{
//Portrait View
}
Works fine for me!