2013-03-13 56 views
3

帮我解决了任务 - 我有一个不能转动它的接口的viewController:如何旋转控制器中不允许旋转其界面的视图?

- (BOOL)shouldAutorotate { 
    return NO; 
} 

- (NSUInteger)supportedInterfaceOrientations { 
    return UIInterfaceOrientationMaskPortrait; 
} 

但我需要旋转它出现在该控制器alertView!所以如果用户旋转设备,alertView应该跟随旋转并且主界面静止不动。我试着订阅通知:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceRotated:) name:UIDeviceOrientationDidChangeNotification object:nil]; 

但在我deviceRotated:我收到这样的有效载荷通知: NSConcreteNotification 0x101dc50 {name = UIDeviceOrientationDidChangeNotification; object = <UIDevice: 0x103e640>; userInfo = { UIDeviceOrientationRotateAnimatedUserInfoKey = 1; }}

什么是UIDeviceOrientationRotateAnimatedUserInfoKey?我如何使用它来了解当前的interfaceOrientation?或者建议获取当前方向并旋转alertView的更好方法。

我试图用

(BOOL)shouldAutorotateToInterfaceOrientation:UIInterfaceOrientation)toInterfaceOrientation

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration但这些方法没有得到所谓的iOS6的:(

此外,是否有任何其他的方法,你可以使用知道该设备正在旋转到某个方向?提前致谢! PS我知道这项任务似乎有点愚蠢,但这是客户的要求。对不起:)对不起:)

回答

5

中有一个orientation变量,其中包含当前设备方向。您可以使用它来代替界面方向(不会像您已经注意到的那样旋转)。

首先你订阅设备方向的变化,好的地方是viewWillAppear和取消对viewWillDisappear

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

- (void)viewWillDisappear:(BOOL)animated { 
    [super viewWillDisappear:animated]; 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
} 

在这个例子中,我们指出,我们要调用到orientationChanged:当设备旋转,使得让实现它:

#pragma mark - Orientation change events 
- (void)orientationChanged:(NSNotification*)notification { 
    UIDeviceOrientation deviceOrientation = [[UIDevice currentDevice] orientation]; 

    // Calculate rotation angle 
    CGFloat angle; 
    switch (deviceOrientation) { 
     case UIDeviceOrientationPortraitUpsideDown: 
      angle = M_PI; 
      break; 
     case UIDeviceOrientationLandscapeLeft: 
      angle = M_PI_2; 
      break; 
     case UIDeviceOrientationLandscapeRight: 
      angle = - M_PI_2; 
      break; 
     default: 
      angle = 0; 
      break; 
    } 

    // Apply rotation 
    static NSTimeInterval animationDuration = 0.3; 
    [UIView animateWithDuration:animationDuration animations:^{ 
     _viewToRotate.transform = CGAffineTransformMakeRotation(angle); 
    }]; 
} 
+0

谢谢,这是最简单的方法。 – Stas 2013-03-14 09:46:09

0

由于方向锁定在特定位置,因此参考状态栏不会有太大的帮助。我的建议是使用加速度计,并根据收到的XYZ值相应地更改alertView。您可以使用CGAffineTransformMakeRotation或CGAffineTransformRotate方法旋转alertView。

使用加速计的一个例子是:

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration{ 
accelerationValue[0] = acceleration.x; 
accelerationValue[1] = acceleration.y; 
accelerationValue[2] = acceleration.z; 
NSLog(@"Acceleration X-axis: %1.1f, Y-axis: %1.1f, Z-axis: %1.1f", acceleration.x, acceleration.y, acceleration.z); 
} 

过程中的加速计将需要建立并创造了各自的ViewController,但我想你明白我的意思。

+0

这有点奇怪......不是iOS 6有更优雅的处理方式吗? – Stas 2013-03-13 16:56:20

+0

@Stas不是我能想到的。事实上,你限制支持的方向是什么使这个问题棘手。 – David 2013-03-13 17:06:31

+0

我们是否有关于我们在iOS 6中旋转的interfaceOrientation的信息(就像我们在iOS5中的方法'willRotateToInterfaceOrientation:'和'shouldRotateToInterfaceOrientation:')? – Stas 2013-03-13 17:30:30

2

我删除了以前的答案,因为我误解了这个问题(其实这是一个非常奇怪的要求,但...)。我建议你使用一个容器视图控制器具有无限旋转面膜,然后添加你的控制器子:CVC旋转事件转发到基于以下方法孩子:

- (BOOL) automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers 
{ 
    return NO; 
} 

所以它会得到所有的事件和只转发给你想要的那个孩子。

最后容器将管理警报并正确旋转它。