如何旋转控制器中不允许旋转其界面的视图?

时间:2013-03-13 16:01:38

标签: iphone ios objective-c ios6 uiinterfaceorientation

帮我解决任务 - 我有一个不允许旋转其界面的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上不会调用这些方法:(

此外,还有其他方法可以用来知道设备正在旋转到某个方向吗?提前致谢! 附:我知道这项任务似乎有点傻,但这是客户的要求。抱歉:)

3 个答案:

答案 0 :(得分:5)

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

首先,您订阅了设备方向更改,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);
    }];
}

答案 1 :(得分:2)

我删除了之前的答案'因为我误解了问题(实际上这是一个非常奇怪的请求,但是......)。我建议你使用带有无限旋转掩码的Container View Controller,然后将你的控制器添加为子节点:CVC根据以下方法将旋转事件转发给子节点:

- (BOOL) automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers
{
    return NO;
}

因此,它将获得所有事件并转发给孩子只有你想要的那个。

最后,Container将管理警报并正确旋转。

答案 2 :(得分: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中设置和创建,但我认为你明白我的观点。