4

帮我解决任务 - 我有一个不允许旋转其界面的 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 我知道这个任务看起来有点傻,但这是客户的要求。对不起 :)

4

3 回答 3

5

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

首先,您订阅设备方向更改,一个好地方是 onviewWillAppear和 unsubscribe on 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);
    }];
}
于 2013-03-13T17:59:56.307 回答
2

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

- (BOOL) automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers
{
    return NO;
}

因此,它将获取所有事件并仅将您想要的事件转发给孩子。

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

于 2013-03-14T08:29:41.220 回答
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 中设置和创建,但我想你明白我的意思。

于 2013-03-13T16:46:06.863 回答