Forced orientation change sometimes does not work

When a certain button is pressed in my application, the view should change the orientation from portrait to landscape. When the user returns, the view controller should return to the portrait. But sometimes the orientation does not change or the wrong angle is used.

Here is my code

-(void)btnSignClicked:(CustomSignButton *)btn { isSignButtonClicked = true; if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_0) { NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight]; [[UIDevice currentDevice] setValue:value forKey:@"orientation"]; } else { [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:YES]; } selectedWaiverId = btn.customTag; SignatureView *obj = [[SignatureView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) delegate:self]; // Most of time got size (568,320) but some time i got (320,568), Don't know why [self.view addSubview:obj]; } #pragma mark - SIGNATUREVIEW DELEGATE -(void)removeSignatureView:(SignatureView *)signatureView { isSignButtonClicked = false; if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_0) { NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait]; [[UIDevice currentDevice] setValue:value forKey:@"orientation"]; // Some time not changed the orientation are view remaining in landscape } else { [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:YES]; } [signatureView removeFromSuperview]; signatureView = nil; } #pragma mark #pragma mark - Rotate screen -(UIInterfaceOrientationMask)supportedInterfaceOrientations { if (isSignButtonClicked == true) { return UIInterfaceOrientationMaskLandscapeRight|UIInterfaceOrientationMaskLandscape; } else { return UIInterfaceOrientationMaskPortrait; } } - (BOOL)shouldAutorotate { return YES; } -(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { if (isSignButtonClicked == true) { return (interfaceOrientation == UIInterfaceOrientationLandscapeRight); } else { return (interfaceOrientation == UIInterfaceOrientationPortrait); } } 

UPDATE

Sometimes the viewWillTransitionToSize method viewWillTransitionToSize not called, so I also integrate this notification

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange:) name:UIDeviceOrientationDidChangeNotification object:nil]; [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; 

But sometimes it also does not work.

+6
source share
5 answers

Add to the file AppDelegate.m or any file of the base controller

  @implementation UINavigationController (Orientation) - (UIInterfaceOrientationMask) supportedInterfaceOrientations { return [(UIViewController*)[[self viewControllers] lastObject] supportedInterfaceOrientations]; } - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { return [(UIViewController*)[[self viewControllers] lastObject] preferredInterfaceOrientationForPresentation]; } - (BOOL) shouldAutorotate { return [(UIViewController*)[[self viewControllers] lastObject] shouldAutorotate]; } @end 

Now put the ViewController object in the UINavigationController object and click on the view controller.

EX.

 UINavigationController *obj=[[UINavigationController alloc] initWithRootViewController:_yourViewCtrlObj]; [self presentViewController:obj.....]; or [self.navigationController pushViewController:obj animated:YES]; 

Set the desired orientation in all controllers.

+2
source

If your application uses the UINavigationViewController, then create a custom class for the UINAvigationController Like:

//CustomNavViewController.h

 #import <UIKit/UIKit.h> @interface CustomNavViewController : UINavigationController <UINavigationControllerDelegate> @end 

//CustomNavViewController.m

 #import "CustomNavViewController.h" @interface CustomNavViewController () @end @implementation CustomNavViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (BOOL)shouldAutorotate { return [self.visibleViewController shouldAutorotate]; } - (UIInterfaceOrientationMask)supportedInterfaceOrientations { return [self.visibleViewController supportedInterfaceOrientations]; } @end 

And now in your AppDelegate declare a Like property:

//AppDelegate.h

  @property (assign, nonatomic) BOOL shouldRotate; 

//AppDelegate.m

 - (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window { if (self.shouldRotate) { return UIInterfaceOrientationMaskLandscapeLeft|UIInterfaceOrientationMaskLandscapeRight; } return UIInterfaceOrientationMaskPortrait; } 

Now you can call the orientation methods in the ViewController, which require a fixed orientation. How:

//YourViewController.m

 -(BOOL)shouldAutorotate{ return NO; } - (UIInterfaceOrientationMask)supportedInterfaceOrientations{ return UIInterfaceOrientationMaskLandscape; } - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{ return UIInterfaceOrientationLandscapeLeft; } 

Now here is the AppDelegate shouldRotate trick set is true and false for the desired orientation

if you use the default view for the ViewController then

 AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate; [appDelegate setShouldRotate:true];// Remember first update the value then present the ViewController [self presentViewController:yourViewController animated:YES completion:nil]; 

Same as releasing

  AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate; [appDelegate setShouldRotate:false]; [self dismissViewControllerAnimated:YES completion:nil]; 

If you are using storyBoards, add the CustomNavViewController directly to the Custom class section of the Inspector Custom class

customNav And then follow these steps. Hope it works.

+1
source

When you say: โ€œWhen the user returns, the view controller must return to the portraitโ€, do you mean that the user clicks the back button on the navigation controller? If so, I saw this problem earlier and posted a solution that worked for me in another SO post: A: Impossibility to block device orientation when viewing in NavBar . I remember that the transition was rough, but it worked.

I also wrote a blog post that looks at some other situations around dispatcher orientation blocking.

+1
source

See the link, in particular, I think you should check the conditions of your view controllers so that they comply with Apple recommendations

eg. check supportedInterfaceOrientations method of the top-most full-screen view controller

0
source

Try adding your entire rotation change code to your block.

 dispatch_async(dispatch_get_main_queue(), { //changing orientation code + isSignButtonClicked = true (or false) }); 

You do not need to use shouldAutorotate and shouldAutorotateToInterfaceOrientation .

As for the incorrect view of frames, you need to use autodetection restrictions for each view that you use in this view manager, even if you create the views programmatically

0
source

All Articles