iOS 8/7 UIWindow存在UIWindowLevelStatusBar旋转问题

iOS 8/7 UIWindow存在UIWindowLevelStatusBar旋转问题,ios,uiwindow,Ios,Uiwindow,我正在尝试添加一个带有UIWindowLevelStatusBarlevel的UIWindow。它在ipad上以肖像模式工作非常完美,但在旋转设备后,它就乱七八糟了 在iOS 7.x上,除了上下颠倒之外,所有旋转都很好,而在iOS 8.x上,只有纵向模式是好的,所有其他方向都是混乱的。你知道怎么解决吗 CGRect frame = [UIApplication sharedApplication].statusBarFrame; self.statusWindow = [[UIWindow al

我正在尝试添加一个带有
UIWindowLevelStatusBar
level的UIWindow。它在ipad上以肖像模式工作非常完美,但在旋转设备后,它就乱七八糟了

在iOS 7.x上,除了上下颠倒之外,所有旋转都很好,而在iOS 8.x上,只有纵向模式是好的,所有其他方向都是混乱的。你知道怎么解决吗

CGRect frame = [UIApplication sharedApplication].statusBarFrame;
self.statusWindow = [[UIWindow alloc] initWithFrame:CGRectMake(frame.origin.x, frame.origin.y, frame.size.width, 20)];

UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
CGRect frame = [UIApplication sharedApplication].statusBarFrame;
CGAffineTransform test = [self transformForOrientation:orientation];

[self.statusWindow setWindowLevel:UIWindowLevelStatusBar];
[self.statusWindow setHidden:NO];


- (CGAffineTransform)transformForOrientation:(UIInterfaceOrientation)orientation
{
 switch (orientation)
 {
    case UIInterfaceOrientationLandscapeLeft:
        return CGAffineTransformMakeRotation(-DEGREES_TO_RADIANS(90.0f));

    case UIInterfaceOrientationLandscapeRight:
        return CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(90.0f));

    case UIInterfaceOrientationPortraitUpsideDown:
        return CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(180.0f));

    case UIInterfaceOrientationPortrait:
    default:
        return CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(0.0f));
}
}

在UIWindow子类的init方法中,请注意以下通知:

// Rotation Notifications
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChangeOrientation:) name:UIDeviceOrientationDidChangeNotification object:nil];

self.baseT = self.transform;
然后方法本身:

- (void)didChangeOrientation:(NSNotification *)n
{

    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;

    switch (orientation) {
        case UIInterfaceOrientationPortrait:
            self.transform = CGAffineTransformRotate(self.baseT, 0);
            break;
        case UIInterfaceOrientationPortraitUpsideDown:
            self.transform = CGAffineTransformRotate(self.baseT, M_PI);
            break;
//      Home button on left
        case UIInterfaceOrientationLandscapeLeft:
            self.transform = CGAffineTransformRotate(self.baseT, -M_PI_2);
            break;
        case UIInterfaceOrientationLandscapeRight:
            self.transform = CGAffineTransformRotate(self.baseT, M_PI_2);
            break;
        default:
            self.transform = CGAffineTransformMakeRotation(0);
            break;
    }
}

根据您的实现,您可能还必须确保帧不会更改。另外,在类的“dealloc”方法中,停止侦听通知。

作为对@dezinezync答案的修改:如果将旋转放在视图控制器的
willrotateTointerfaceooritation
方法中,则执行旋转效果会更好。这样,仅当设备旋转到应用程序构建设置的General->Deployment Info部分中指定的支持方向之一时,才会应用旋转。作为额外的奖励,您可以访问旋转动画的持续时间。只需确保在视图控制器中有对模式窗口的引用

无论支持什么方向,只要屏幕方向改变,就会触发
UIDeviceOrientationIDChangeNotification
通知。这可能导致不受欢迎的行为

下面是一个例子:

UIWindow *modalWindow;

// Initialize your modal window somewhere in your code
// ...

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];

    // Make sure the modalWindow exists
    if (modalWindow != nil)
    {
        // Animate the modal window's rotation
        [UIView animateWithDuration:duration animations:^{
            [self rotateModal:modalWindow];
        }];
    }
}

- (void)rotateModal:(UIWindow*)window
{

    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;

    switch (orientation) {
        case UIInterfaceOrientationPortrait:
            window.transform = CGAffineTransformRotate(self.baseT, 0);
            break;
        case UIInterfaceOrientationPortraitUpsideDown:
            window.transform = CGAffineTransformRotate(self.baseT, M_PI);
            break;
//      Home button on left
        case UIInterfaceOrientationLandscapeLeft:
            window.transform = CGAffineTransformRotate(self.baseT, -M_PI_2);
            break;
        case UIInterfaceOrientationLandscapeRight:
            window.transform = CGAffineTransformRotate(self.baseT, M_PI_2);
            break;
        default:
            window.transform = CGAffineTransformMakeRotation(0);
            break;
    }
}
我只是在一个只支持横向的应用程序上做了类似的事情,我最终通过将所有内容移动到
willRotateToInterfaceOrientation
方法使其正常工作。

iOS8解决方案(也需要如上所示的转换):


但是,它不适用于iOS9测试版。

这是处理定向支持的高度随机的方法。您甚至不应该考虑转换任何东西,因为只要您正确设置
rootViewController
属性,
UIWindow
就可以并将为您处理所有事情。代码中缺少一些东西,显示与您的状态窗口相关的所有代码。为了澄清,此代码将在状态栏上设置另一个uiwindow。因此,没有rootviewcontroller。如果我不转换uiwindow,它将保持纵向模式,在iOS 7和iOS 8上都不会旋转,因此必须手动旋转。如果您知道更好的方法,请共享。旋转确实有效,但uiwindow未根据屏幕方向正确定位和调整大小。无论如何,谢谢你的努力。
UIScreen *screen = [UIScreen mainScreen];
CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame;
if ([screen respondsToSelector:@selector(fixedCoordinateSpace)])
{
    [self setFrame:[screen.coordinateSpace convertRect:statusBarFrame toCoordinateSpace:screen.fixedCoordinateSpace]];
}