No.11 Xcode(5.1.x) 设备或程序旋转

参考:http://blog.sina.com.cn/s/blog_6291e42d0102v0th.html

1.工程配置和回调方法

    在工程的配置选项里, 可以设置程序所允许的方向;

    在配置选项的前提下, 在视图控制器里有关于当前视图可允许的旋转回调, 这个回调只对rootViewController和presentedViewController有效, 对于子级的视图控制器无效. 例如UINavigationController作为根视图时, 旋转回调需要设置在UINavigationController上, 设置在UINavigationController的子控制器上是没有效果的.

2.关于方向

    这里有三种方向:手机方向[[UIDevice currentDevice] orientation], 程序方向[[UIApplication sharedApplication] statusBarOrientation], 视图方向.

    手机方向: set方法被官方作为私有api禁用, 但是可以绕过限制. 这个方法可以看做是摇动手机. 据我估计, 旋转手机时, 系统会调用这个set方法, 所以, 当想要不旋转手机而使屏幕旋转时, 需要主动调用这个方法. 实际旋转效果会受到工程配置项和回调方法的影响.

    程序方向: 实际旋转效果会受到工程配置项和回调方法的影响.

    视图方向: 通过设置transform属性可以使视图旋转, 但是如果此时有键盘或者提示框或者状态栏存在, 会发现它们仍是原来的方向.

3.旋转方案

    方案1:调用[[UIDevice currentDevice] setOrientation:]方法, 使程序旋转, 需要配置旋转回调, 回调的配置必须在根视图上

@implementation ViewController

- (void)loadView
{
    [super loadView];
        
    UIButton *showButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    showButton.frame = CGRectMake(210, 20, 50, 50);
    showButton.layer.borderWidth = 1;
    [showButton setTitle:@"旋转" forState:UIControlStateNormal];
    [showButton addTarget:self action:@selector(showButtonPressed) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:showButton];
}

- (void)showButtonPressed
{
    if (self.bLandscapeRight)
    {
        self.bLandscapeRight = NO;
        [self forceOrientation:UIInterfaceOrientationPortrait];
    }
    else
    {
        self.bLandscapeRight = YES;
        [self forceOrientation:UIInterfaceOrientationLandscapeRight];
    }
}

- (BOOL)shouldAutorotate
{
    return YES;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
    return self.bLandscapeRight ? UIInterfaceOrientationMaskLandscapeRight : UIInterfaceOrientationMaskPortrait;
}

- (void)forceOrientation: (UIInterfaceOrientation)orientation
{
    if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)])
    {
        SEL selector = NSSelectorFromString(@"setOrientation:");
        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
        [invocation setSelector:selector];
        [invocation setTarget: [UIDevice currentDevice]];
        int val = orientation;
        [invocation setArgument:&val atIndex:2];
        [invocation invoke];
    }
}

@end

    方案2:弹出新的presentedViewController, 并设置其方向

UILandscapeView *landscapeView = [[UILandscapeView alloc] init];
[self presentViewController:landscapeView animated:YES completion:nil];
@implementation UILandscapeView

- (void)loadView
{
    [super loadView];
    
    self.view.backgroundColor = [UIColor orangeColor];
    
    UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 20, 180, 50)];
    textField.backgroundColor = [UIColor redColor];
    textField.text = @"1111122222";
    [self.view addSubview:textField];
    
    UIButton *showButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    showButton.frame = CGRectMake(210, 20, 50, 50);
    showButton.layer.borderWidth = 1;
    [showButton setTitle:@"弹框" forState:UIControlStateNormal];
    [showButton addTarget:self action:@selector(showButtonPressed) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:showButton];
    
    UIButton *backButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    backButton.frame = CGRectMake(270, 20, 50, 50);
    backButton.layer.borderWidth = 1;
    [backButton setTitle:@"返回" forState:UIControlStateNormal];
    [backButton addTarget:self action:@selector(backButtonPressed) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:backButton];
}

- (BOOL)shouldAutorotate
{
    return YES;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscape;
}

- (void)backButtonPressed
{
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)showButtonPressed
{

}

@end

以下是过去的想法

1. 利用通常的方式来控制旋转方向: 在工程配置中允许设备向某几个方向旋转, 然后在某个视图只允许向某几个方向旋转;

2. 利用消息中心 [NSNotificationCenter defaultCenter] 来监测设备旋转, 哪怕在工程配置中不允许的旋转方向, 也会被监测到, 并且检测到的方向是UIDeviceOrientation代表的七种方向;

3. 利用私有API或者是隐藏的API接口, 主动使界面旋转, 哪怕设备并没有转动;

4. 利用view.transform属性来旋转视图, 缺点是: 当有系统控件, 比如UIAlertView时, 这个控件的方向还是原来的;


一般方法

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscapeLeft; // 允许旋转的方向
}

- (BOOL)shouldAutorotate
{
    return YES;
}

消息中心

- (void)viewWillAppear:(BOOL)animated
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceRotated:) name:UIDeviceOrientationDidChangeNotification object:[UIDevice currentDevice]];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:[UIDevice currentDevice]];
}

- (void)deviceRotated:(UIButton*)button
{
    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
}

强制旋转

- (void)manulRotate:(UIButton*)button
{
    UIDeviceOrientation oldOrientation = [[UIDevice currentDevice] orientation];
    UIDeviceOrientation newOrientation = (oldOrientation == UIDeviceOrientationLandscapeRight) ? UIDeviceOrientationPortrait : UIDeviceOrientationLandscapeRight;
    NSLog(@"orientation from old(%d) to new(%d)", oldOrientation, newOrientation);
    
    // 调用私有API(禁用ARC时)
    //if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)])
    //    [[UIDevice currentDevice] performSelector:@selector(setOrientation:) withObject:(id)UIInterfaceOrientationLandscapeRight];

    // 调用私有API(启用ARC时)
    if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)])
    {
        SEL selector = NSSelectorFromString(@"setOrientation:");
        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
        [invocation setSelector:selector];
        [invocation setTarget:[UIDevice currentDevice]];
        int val = newOrientation;
        [invocation setArgument:&val atIndex:2];
        [invocation invoke];
    }
}

旋转视图

- (void)viewRotate:(UIButton*)button
{
    // 旋转window
    //self.view.window.transform = CGAffineTransformRotate(self.view.window.transform, M_PI/2);
    
    // 旋转view
    self.view.transform = CGAffineTransformRotate(self.view.transform, M_PI/2);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值