具有UIWindowLevelStatusBar旋转问题的iOS 8/7 UIWindow

时间:2014-11-17 15:50:19

标签: ios uiwindow

我尝试添加UIWindowLevelStatusBar级别的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));
}
}

3 个答案:

答案 0 :(得分:0)

在你的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方法,停止收听通知。

答案 1 :(得分:0)

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

无论支持哪种方向,只要屏幕方向发生变化,就会触发UIDeviceOrientationDidChangeNotification通知。这可能导致不良行为。

以下是一个例子:

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方法来使其正常工作。

答案 2 :(得分:0)

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

UIScreen *screen = [UIScreen mainScreen];
CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame;
if ([screen respondsToSelector:@selector(fixedCoordinateSpace)])
{
    [self setFrame:[screen.coordinateSpace convertRect:statusBarFrame toCoordinateSpace:screen.fixedCoordinateSpace]];
}

然而,它不适用于iOS9测试版。