强制方向改变有时不起作用

当我的应用程序中按下某个button时,视图应该将方向从纵向改为横向。 当用户回来时,视图控制器应该改回肖像。 但有时方向不会改变或使用错误的视图框架。

这是我的代码

-(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

有时候viewWillTransitionToSize方法没有被调用,所以我也整合了这个通知

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

但有时这也是行不通的。

添加AppDelegate.m文件或​​任何基础控制器文件

  @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 

现在把你的ViewController对象放在UINavigationController对象中,然后推视图控制器。

EX。

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

在所有视图控制器中设置所需的方向。

如果您的应用程序使用UINavigationViewController,那么为UINAvigationController创build一个自定义类如:

//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 

现在在你的AppDelegate声明一个属性像:

//AppDelegate.h

  @property (assign, nonatomic) BOOL shouldRotate; 

//AppDelegate.m

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

现在你可以调用定位方法到需要修复方向的ViewController。像:

//YourViewController.m

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

现在,这里是把AppDelegate的shouldRotate属性设置为true和false为所需的方向

如果你正在使用默认演示ViewController然后

 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]; 

和你解雇时一样

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

如果您正在使用storyBoards,则直接在Identity Inspector Custom类部分添加CustomNavViewController

customNav 之后,按照上述步骤。 希望它的工作

当你说“当用户回来,视图控制器应该改回肖像”,你的意思是用户正在点击导航控制器上的后退button? 如果是这样,我以前看到这个问题,并发布了一个解决scheme,在另一个SOpost中为我工作: 答:在NavBar中返回时,在视图上locking设备方向失败 。 我记得过渡是粗糙的,但它的工作。

我也写了一篇博客文章 ,看看围绕视图控制器方向locking的其他一些情况。

看到这个链接 ,特别是我觉得你应该检查一下你的视图控制器的状况,以便它们符合苹果的build议

例如,检查最顶级的全屏视图控制器的supportedInterfaceOrientations方法

尝试添加此块内的所有旋转更改代码

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

您不必使用shouldAutorotateshouldAutorotateToInterfaceOrientation

至于视图框架出错,您需要为您在viewController中使用的每个视图使用自动布局约束,即使您是以编程方式创build视图