Displaying Game Center modal view in landscape - iphone

I am using cocos2d engine in landscape-only orientation with no autorotation.
I want to display standart GC achievements modal view.
It's showing up normally, from bottom of screen (while holding device in landscape), but it is dismissing to the right side of the screen (like portrait modal views). It's seems to be changing orientation for dismiss animation, but view is not rotating before this. It's just sliding to the right.
Also I get a warning in console:
Unbalanced calls to begin/end appearance transitions for <UIViewController: 0x41b9a0>.
That's how I showing this controller:
-(void)showAchievements:(id) sender {
utilityController = [[UIViewController alloc] initWithNibName:nil bundle:nil];
[[[CCDirector sharedDirector] openGLView] addSubview:utilityController.view];
GKAchievementViewController *achievements = [[GKAchievementViewController alloc] init];
if (achievements != nil)
{
achievements.achievementDelegate = self;
[utilityController presentModalViewController: achievements animated: YES];
}
[achievements release];
}
- (void)achievementViewControllerDidFinish:(GKAchievementViewController *)viewController
{
[utilityController dismissModalViewControllerAnimated:YES];
[utilityController release];
}
In gameConfig.h I have following configuration:
#define GAME_AUTOROTATION kGameAutorotationNone
Tried to change this to kGameAutorotationCCDirector - same thing. kGameAutorotationUIViewController - uiviews are jumping all over the screen.
Please do not suggest rotating UIView with CGAffineTransformMakeRotation - it's just a hack...

For Kobold2D I solved this for all orientations with a category for the GKMatchmakerViewController. You can make the same category for the other Game Center view controllers.
This will force the GC views to use the current device orientation:
#implementation GKMatchmakerViewController (OrientationFix)
-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// [RootViewController option removed for clarity]
// all other autorotation types use the current device orientation
ccDeviceOrientation orientation = [CCDirector sharedDirector].deviceOrientation;
switch (interfaceOrientation)
{
case UIInterfaceOrientationPortrait:
return (orientation == kCCDeviceOrientationPortrait);
break;
case UIInterfaceOrientationPortraitUpsideDown:
return (orientation == kCCDeviceOrientationPortraitUpsideDown);
break;
case UIInterfaceOrientationLandscapeLeft:
return (orientation == kCCDeviceOrientationLandscapeRight);
break;
case UIInterfaceOrientationLandscapeRight:
return (orientation == kCCDeviceOrientationLandscapeLeft);
break;
default:
break;
}
return NO;
}
#end

This is my first ever answer on Stackoverflow, so please forgive me if any formatting may not work.
Anyway, on to the code. This solution works for me, for the Achievements-Viewcontroller. Any other GK-Viewcontroller may work accordingly...
#implementation GKAchievementViewController (OrientationFix)
-(BOOL) shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{
return UIInterfaceOrientationIsLandscape(interfaceOrientation);
}
#end
#interface GKLeaderboardViewController (OrientationFix)
#end
-(void)showAchievements
{
GKAchievementViewController *achievements = [[GKAchievementViewController alloc] init];
if (achievements != nil)
{
achievements.achievementDelegate = self;
[self presentModalViewController: achievements animated: YES];
}
[achievements release];
}
- (void)achievementViewControllerDidFinish: (GKAchievementViewController *)viewController
{
AppDelegate *delegate = [UIApplication sharedApplication].delegate;
[delegate.viewController dismissModalViewControllerAnimated:YES];
}

Try to call
self.modalPresentationStyle = UIModalPresentationCurrentContext;
Before presenting the ViewController

Related

UIImagePickerControllerCameraDeviceFront works every other time

This question is very similar to an existing question asked here UIImagePickerControllerCameraDeviceFront only works every other time I tried the solution presented but it didn't work for me
I have a simplest of a project with two view controllers. In the blue one I am displaying a small UIView with a UIImagePickerController in it. NOTE: I am displaying front facing camera when app is launched.
I hit the next button and go to orange view controller and when I hit the back button and come back to blue view controller the UIImagePickerController flips from Front to rear. I guess the reason is that it thinks its busy and moves to the rear cam. If I keep moving back and forth between the view controllers the camera keeps flipping front, back, front, back, front, back...
Here is my code and screenshots, what am I doing wrong?
In my *.h
#import <UIKit/UIKit.h>
#interface v1ViewController : UIViewController <UIImagePickerControllerDelegate>
{
UIImagePickerController *picpicker;
UIView *controllerView;
}
#property (nonatomic, retain) UIImagePickerController *picpicker;
#property (nonatomic, retain) UIView *controllerView;
#end
In my *.m file (This code is only used when blue colored view controller is displayed)
#import "v1ViewController.h"
#import <MobileCoreServices/UTCoreTypes.h>
#implementation v1ViewController
#synthesize picpicker;
#synthesize controllerView;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
picpicker = [[UIImagePickerController alloc] init];
picpicker.delegate = self;
picpicker.mediaTypes = [NSArray arrayWithObjects:(NSString *)kUTTypeImage, nil];
picpicker.sourceType = UIImagePickerControllerSourceTypeCamera;
picpicker.cameraDevice = UIImagePickerControllerCameraDeviceFront;
picpicker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
picpicker.showsCameraControls = NO;
picpicker.navigationBarHidden = NO;
picpicker.wantsFullScreenLayout = NO;
controllerView = picpicker.view;
[controllerView setFrame:CGRectMake(35, 31, 250, 250)];
controllerView.alpha = 0.0;
controllerView.transform = CGAffineTransformMakeScale(1.0, 1.0);
[self.view addSubview:controllerView];
[UIView animateWithDuration:0.3
delay:0.0
options:UIViewAnimationOptionCurveLinear
animations:^{
controllerView.alpha = 1.0;
}
completion:nil
];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[picpicker dismissModalViewControllerAnimated:YES];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[picpicker dismissModalViewControllerAnimated:YES];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
} else {
return YES;
}
}
#end
You are dismissing the controller in both the viewDidDisappear and viewWillDisappear methods.
That could be the cause of your problem.
Although I do not have a device with a camera available right now to verify this, it seems that you're not dismissing the pickerview controller correctly. The documentation states that you should call dismissModalViewControllerAnimated: on the parent controller in order to dismiss the picker (though, calls to presented controllers will propagate to presenters - so this is not the problem), but in your case you're not displaying the controller modally in the first place so it will not work.
What I would try in this case is to release the picker instead (if not under ARC) and set it to nil (instead of calling [picpicker dismissModalViewControllerAnimated:YES];).
PS. In fact, it seems that there is a bigger problem with your design. Since each button is set to present the other party modally you are not dismissing any of the controllers ever. The controllers just keep stacking on each other. You should either consider to embed them in a navigation controller and have it handle the hierarchy or just set dismissModalViewControllerAnimated: (dismissViewControllerAnimated:completion: on iOS5+) as the action of the second controller's button instead of a modal segue.
This is a very simple issue. I don't know why this happens exactly, but it seems that UIImagePickerController was designed to recreated each time it's needed instead of keeping any reference to it, which seems logical if you think about it. Basically, you need to recreate and reconfigure your picker each time. Below I've pasted some code to give an image of what I mean.
Simple solution:
- (UIImagePickerController *)loadImagePicker {
UIImagePickerController *picpicker = [[UIImagePickerController alloc] init];
picpicker.delegate = self;
picpicker.mediaTypes = [NSArray arrayWithObjects:(NSString *)kUTTypeImage, nil];
picpicker.sourceType = UIImagePickerControllerSourceTypeCamera;
picpicker.cameraDevice = UIImagePickerControllerCameraDeviceFront;
picpicker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
picpicker.showsCameraControls = NO;
picpicker.navigationBarHidden = NO;
picpicker.wantsFullScreenLayout = NO;
return picpicker;
}
and in:
-(void)viewWillAppear:(BOOL)animated{
if(!self.picpicker){
self.picpicker = [self loadImagePicker];
[self.view addSubview: self.picpicker];
}
}
-(void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.picpicker removeFromSuperview];
self.picpicker = nil;
}

How to set a view to a tag set in code not in Interface Builder?

I have an app that uses 4 different xibs, lets call them 1-4
So you start on view 1, if you press the button it takes you to view 2, on view 2, you have a back button (which takes you to 1) and forward button that takes you to 3 etc
Anyway, I am removing the next page buttons, and have added a swipe control instead of pressing a button, you can swipe to the next page.
However, I need to know how I can call a tagged view, using the swipe.
At the moment, the UIButton for next page is set in IB as tag 1
This is my swipe code (this is page 1 so only has a swipe left)
- (IBAction)swipeLeftDetected:(UIGestureRecognizer *)sender {
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
Page2ViewController *UIViewController =
[[Page2ViewController alloc] initWithNibName:#"Page2ViewController~ipad" bundle:nil];
[self presentModalViewController:UIViewController animated:YES];
}else{
Page2ViewController *UIViewController =
[[Page2ViewController alloc] initWithNibName:#"Page2ViewController" bundle:nil];
[self presentModalViewController:UIViewController animated:YES];
Page2ViewController *VC = [[Page2ViewController alloc] initWithNibName:#"Page2ViewController" bundle:nil];
[self presentModalViewController:VC animated:YES];
[self.view removeGestureRecognizer:[self.view.gestureRecognizers lastObject]];
[VC release];
}
}
Whereabout in that code, can I tell it to swipe to tag 1?
Would appreciate any help :)
Thanks,
Chris
---- Updated FAO Rob;
In the appdelegate.m
- (void)swicthView:(int)viewControllerIndex :(CGRect)viewRect {
if (viewControllerIndex < 0 || viewControllerIndex > viewControllers.count) {
//invalid index passed to function - do nothing
}else{
if (subViewForceUseNibSize == NO) {
//pass the view frame size at runtime
if (CGRectIsEmpty(viewRect) || viewControllerIndex == 0) {
//no frame size so force full screen
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
viewRect =CGRectMake(0, 0, 320, 480);
}else{
viewRect = CGRectMake(0, 0, 768, 1024);
}
}
}else{
//force use the nib size, so reduce size of NIB to leave display of NIB main nib below
viewRect = ((UIViewController *)[viewControllers objectAtIndex:viewControllerIndex]).view.frame;
}
}
//swicth our view
if (viewControllerIndex == 0) {
/*
for (UIView *subview in window.rootViewController.view.subviews) {
[window.rootViewController.view sendSubviewToBack:subview];
}
*/
for (int x = 1; x<[viewControllers count]; x++) {
if (((UIViewController *)[viewControllers objectAtIndex:x]).view.superview != nil) {
[window.rootViewController.view sendSubviewToBack:((UIViewController *)[viewControllers objectAtIndex:x]).view];
}
}
[window bringSubviewToFront:((UIViewController *)[viewControllers objectAtIndex:0]).view];
return;
}
if (((UIViewController *)[viewControllers objectAtIndex:viewControllerIndex]).view.superview != nil) {
((UIViewController *)[viewControllers objectAtIndex:viewControllerIndex]).view.frame = viewRect;
[window.rootViewController.view bringSubviewToFront:((UIViewController *)[viewControllers objectAtIndex:0]).view];
[window.rootViewController.view bringSubviewToFront:((UIViewController *)[viewControllers objectAtIndex:viewControllerIndex]).view];
}else{
((UIViewController *)[viewControllers objectAtIndex:viewControllerIndex]).view.frame = viewRect;
[window.rootViewController.view bringSubviewToFront:((UIViewController *)[viewControllers objectAtIndex:0]).view];
[window.rootViewController.view addSubview:((UIViewController *)[viewControllers objectAtIndex:viewControllerIndex]).view];
}
}
Looking at the revised code sample, it is clear that there is a UIAppDelegate method called swicthView [sic] that is used for transitioning between five different view controllers, all of which are loaded simultaneously. Given this structure, it is advised that you have a property to keep track of which of the five pages is loaded, and based on the left or right swipe, invoke swicthView to transition to that controller. Thus:
#interface ViewController ()
#property (nonatomic) NSInteger currentPage;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.currentPage = 0;
UISwipeGestureRecognizer *gesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleLeftSwipe:)];
gesture.direction = UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:gesture];
[gesture release];
gesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleRightSwipe:)];
gesture.direction = UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:gesture];
[gesture release];
// the rest of the viewDidLoad
}
- (void)handleLeftSwipe:(UISwipeGestureRecognizer *)gesture {
if (self.currentPage < 4)
{
++self.currentPage;
[UIAppDelegate swicthView:self.currentPage :CGRectZero];
}
}
- (void)handleRightSwipe:(UISwipeGestureRecognizer *)gesture {
if (self.currentPage > 0)
{
--self.currentPage;
[UIAppDelegate swicthView:self.currentPage :CGRectZero];
}
}
Frankly, I'd strong advise retiring the swicthView design and rather employing a custom container view controller. If you watch WWDC 2011 - Implementing a UIViewController containment, you'll see a good introduction about the importance of keeping a view controller hierarchy synchronized with a view hierarchy, and see some practical demonstrations of custom containers.
The original answer, provided below, was based upon the original snippet of code that was performing presentViewController. It turns out that a very different solution was called for, outlined above, but I retain the original answer for historical purposes:
Original answer:
I assume you have the following sort of code in viewDidLoad:
UISwipeGestureRecognizer *gesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleLeftSwipe:)];
gesture.direction = UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:gesture];
And then you gesture handler could be:
- (void)handleLeftSwipe:(UISwipeGestureRecognizer *)gesture
{
NSString *nibName;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
nibName = #"Page2ViewController~ipad";
else
nibName = #"Page2ViewController";
Page2ViewController *controller = [[Page2ViewController alloc] initWithNibName:nibName bundle:nil];
// if supporting iOS versions earlier than 5.0, then you should use:
//
// [self presentModalViewController:controller animated:YES];
//
// otherwise you should use presentViewController as done below.
[self presentViewController:controller animated:YES completion:nil];
[controller release];
}
Note, I'm don't remove the gesture (unless you really don't want the gesture there when you return back to this view, which is unlikely). Also note, I'm creating controller, presenting, and releasing.
I'm not understanding your repeated reference to tag properties in this context, as numeric tag values are used for identifying subviews of a view, not for identifying view controller or anything like that. So you say "UIButton for next page is set in IB as tag 1" and later you ask "Whereabout ... can I tell it to swipe to tag 1?" It doesn't make sense to "swipe to a button". You could, though, have the two handlers, the button's IBAction (which I'll call onPressNextButton ... I don't know what you called it) and the handleLeftSwipe call the same method, e.g.:
- (void)handleLeftSwipe:(UISwipeGestureRecognizer *)gesture
{
[self goToNextViewController];
}
- (IBAction)onPressNextButton:(id)sender
{
[self goToNextViewController];
}
- (void)goToNextViewController
{
NSString *nibName;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
nibName = #"Page2ViewController~ipad";
else
nibName = #"Page2ViewController";
Page2ViewController *controller = [[Page2ViewController alloc] initWithNibName:nibName bundle:nil];
[self presentViewController:controller animated:YES completion:nil];
[controller release];
}
References:
presentViewController, the preferred method for modal transitions.
presentModalViewController, the now deprecated method that you use if you need backward compatibility for iOS versions prior to 5.0.
Naming basics in the Coding Guidelines for Cocoa, for advice in naming variables and methods. Note variables generally start with lowercase letters and classes generally start with uppercase letters.

Dismissing camera view crashes app

When I try to dismiss my UIImagePickerController, it crashes the app. the error is: "Terminating app due to uncaught exception 'UIApplicationInvalidInterfaceOrientation', reason: 'preferredInterfaceOrientationForPresentation must return a supported interface orientation!'"
I have the preferred interface orientation set in my view controller.
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return UIInterfaceOrientationIsPortrait(interfaceOrientation);
}
- (BOOL) shouldAutorotate {
return YES;
}
Here is the method I'm calling to bring up the camera, this works fine for adding the camera, but like I said, crashes when I try to remove the camera.
-(IBAction)addCamera:(id)sender
{
self.cameraController = [[UIImagePickerController alloc] init];
self.cameraController.sourceType = UIImagePickerControllerSourceTypeCamera;
self.cameraController.cameraViewTransform = CGAffineTransformScale(self.cameraController.cameraViewTransform,
1.13f,
1.13f);
self.cameraController.showsCameraControls = NO;
self.cameraController.navigationBarHidden = YES;
self.wantsFullScreenLayout = YES;
ar_overlayView = [[UIView alloc] initWithFrame:CGRectZero];
self.view = ar_overlayView;
[self.cameraController setCameraOverlayView:ar_overlayView];
[self presentViewController:cameraController animated:NO completion:nil];
[ar_overlayView setFrame:self.cameraController.view.bounds];
}
-(IBAction)back:(id)sender
{
[ar_overlayView removeFromSuperview];
[cameraController dismissViewControllerAnimated:NO completion:nil];
}
Alright, found the solution, it was really simple, I just changed my back method to:
[self dismissModalViewControllerAnimated:YES];
Now my camera goes away and I can see my original view when I press the back button.
I still haven't figured out what was causing the original problem as I've gone through the info.plist and the methods for supported orientations, but this accomplishes what I wanted.
I'm still curious as to what was causing the error though if anyone has any ideas.
You can try remove this method:
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
It will fix it.but sometimes it will lead to reduce stateBar height.
You cannot remove a UIViewController's main view from its superview.
Instead of this:
self.view = ar_overlayView;
Try this:
[self.view addSubview:ar_overlayView];
Then you will be able to remove it from the superview correctly.
You should be using the didFinishPickingMedieWithInfo method similar to below and use [self dismissModalViewControllerAnimated:YES];
-(void) imagePickerController:(UIImagePickerController *) picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
NSLog(#"Camera");
}
else {
NSLog(#"Album");
}
[self dismissModalViewControllerAnimated:YES];
}
I don't think you need to add ar_overlayView to the current view yourself if it's a camera overlay.
Here's what your code is doing now:
Add ar_overlayView to the current view
Add ar_overlayView as the camera's overlay view
Show the camera view (modal)
At this point, ar_overlayView is being displayed twice. When you send it the removeFromSuperview message on dismissing the camera view, it might be getting confused since it's in two view hierarchies at the same time.
Skipping the self.view = ar_overlayView; or [self.view addSubview:ar_overlayView]; lines should fix the problem.
Also, dismissViewControllerAnimated:completion: should be sent to the same object that presentViewController:animated:completion was called on (self in this case):
-(IBAction)addCamera:(id)sender
{
// -- snip -- //
ar_overlayView = [[UIView alloc] initWithFrame:self.cameraController.view.bounds];
[self.cameraController setCameraOverlayView:ar_overlayView];
[self presentViewController:self.cameraController animated:NO completion:nil];
}
-(IBAction)back:(id)sender
{
[self dismissViewControllerAnimated:NO completion:nil];
}

setStatusBarOrientation issue

I have a navigation controller app. And first I push FirstViewController (support Portrait orientation) and then SecondViewController (supports all orientations). When I'm in landscape mode of SecondViewController and press back button, FirstViewController appears in landscape mode. That's why I manually rotate the navigation view, but when I want to set setStatusBarOrientation to Portrait (First view controller should appears only in portrait mode), the orientation of view controller is still landscape, and even if rotate the device to portrait mode, the orientation stay landscape
.Here is my code of FirstViewController:
- (void)viewWillAppear:(BOOL)animated
{
if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation))
{
if (self.interfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
prevInterfaceOrientation = UIInterfaceOrientationLandscapeLeft;
self.navigationController.view.transform = CGAffineTransformIdentity;
self.navigationController.view.transform =
CGAffineTransformMakeRotation(degreesToRadians(90));
}
else if (self.interfaceOrientation ==
UIInterfaceOrientationLandscapeRight) {
prevInterfaceOrientation = UIInterfaceOrientationLandscapeRight;
self.navigationController.view.transform = CGAffineTransformIdentity;
self.navigationController.view.transform =
CGAffineTransformMakeRotation(degreesToRadians(-90));
}
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
[self.tableViewDetail reloadData];
}
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if (toInterfaceOrientation == UIInterfaceOrientationPortrait)
{
if (prevInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
self.navigationController.view.transform = CGAffineTransformIdentity;
}
else if (prevInterfaceOrientation ==
UIInterfaceOrientationLandscapeRight) {
self.navigationController.view.transform = CGAffineTransformIdentity;
}
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
[self.tableViewDetail reloadData];
}
}
I even tried to use:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
if (UIInterfaceOrientationIsLandscape(prevInterfaceOrientation))
{
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
}
}
but self.interfaceOrientation still stays landscape, when I rotate to portrait.
But I really need to rotate the view to portrait mode manually to allow users to see,that FirstViewController suppors only portrait orientation.
I have the option to put the SecondViewController's view on MainWindow (like modal window), but I don't like this idea, because if apple has setStatusBarOrientation method, it seems to me, that it has to be right solve of this issue.
I would get rid of the transformations, and use
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:animated];
This in combination with the forced redrawing of the view stack will get it done. This can be done by adding the following to viewDidAppear to the first controller (it doesn't work in viewWillApear).
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
if ([window.subviews count] > 0) {
UIView *view = [window.subviews objectAtIndex:0];
[view removeFromSuperview];
[window insertSubview:view atIndex:0];
}
else {
DLog(#"NO view to force rotate?");
}
Unfortunately, the transition animation is not very clean when you do this, so I would recommend taking a snapshot of the portrait screen, overlay this over your view, and then fade it out with a separate animation.
Steven Veltema's answer didn't work for me.
I had one view controller where all orientations where allowed, and the rest only supported portrait. When i had the first view controller in landscape and navigated to another view controller, the orientation didn't refresh as you are experiencing.
I found another trick to reload the views i correct orientation. Just add a modal view controller you don't even see it. Add this in all other views:
- (void)viewDidAppear:(BOOL)animated
{
UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
if(UIInterfaceOrientationIsLandscape(interfaceOrientation)){
UIViewController * viewController = [[UIViewController alloc] init];
[self presentModalViewController:viewController animated:NO];
[viewController dismissModalViewControllerAnimated:NO];
}
[super viewDidAppear:animated];
....
}
Another quick solution is
Click on your project in the left side bar.
In General settings, choose "Hide during application launch" option.

Manually rotate viewcontroller

My app must NOT auto-rotate at all. But it includes a screen which tells the user to rotate his phone (and not the opposite!).
To do that, the ViewController must make an animated rotation (without any rotation event) when the screen is displaying.
So I used
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft animated:animated];
}
- (void)viewWillDisappear:(BOOL)animated {
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:animated];
[super viewWillDisappear:animated];
}
And
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return YES;
}
to make my screen rotate, as every website and documentation recommend.
But only the StatusBar rotates: my NavigationBar remains stuck at the top.
I would use a CGAffineTransform perhaps on the navigationcontroller view? Simply rotate it using an animation block 90 degrees?
this code is helpful for you to resize the navigation bar automatically you can use it in where you create the navigationController & navigation bar
self.navigationController.navigationBar.autoresizesSubviews = YES;
self.navigationController.navigationBar.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
above code will work automatically if it is not then you try this will work in all delegates methods of your view controller where you need the change
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft animated:animated];
[self.navigationController shouldAutorotateToInterfaceOrientation:[UIApplication sharedApplication].statusBarOrientation];
}
- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
CGRect frame = self.navViewController.navigationBar.frame;
frame.size = self.view.frame.size;
if (toInterfaceOrientation == UIInterfaceOrientationPortrait || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
frame.size.height = 44;
} else {
frame.size.height = 32;
}
self.navViewController.navigationBar.frame = frame;
if navigation controller is rootview controller then check it enables the all orientation supports
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
[super shouldAutorotateToInterfaceOrientation:toInterfaceOrientation];
[self.navigationController shouldAutorotateToInterfaceOrientation:toInterfaceOrientation];
return YES;
}
you can use this code in viewcontroller delegates listed below according to your requirment
- (void)viewDidAppear:(BOOL)animated
- (void)viewWillAppear:(BOOL)animated
– willRotateToInterfaceOrientation:duration:
– willAnimateRotationToInterfaceOrientation:duration:
– didRotateFromInterfaceOrientation: