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

时间:2016-03-04 11:18:14

标签: ios objective-c ios8 uiinterfaceorientation

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

这是我的代码

-(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);
    }

}

更新

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

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

但有时这也行不通。

5 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

如果您的应用使用UINavigationViewController,则为UINAvigationController创建自定义类,如:

// 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声明了一个属性Like:

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

上添加CustomNavViewController

customNav 然后按照上述步骤操作。希望它的工作

答案 2 :(得分:1)

当您说“当用户回来时,视图控制器应该变回肖像”,您是说用户是否正在点击导航控制器上的后退按钮?如果是这样,我之前看到了这个问题,并在另一个SO帖子中发布了一个对我有用的解决方案:A: Locking device orientation on a view fails when going back in NavBar。我记得过渡很艰难但是很有效。

我还写了一段时间blog post,看看围绕视图控制器方向锁定的其他一些情况。

答案 3 :(得分:0)

特别是,请参阅此link,我认为您应该检查视图控制器的条件,它们是否符合Apple建议

e.g。检查最顶层全屏视图控制器的supportedInterfaceOrientations方法

答案 4 :(得分:0)

尝试在此块中添加所有旋转更改代码

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

您无需使用shouldAutorotateshouldAutorotateToInterfaceOrientation

对于出错的视图框架,即使您以编程方式创建视图,也需要对此viewController中使用的每个视图使用自动布局约束