iOS 8 / 7 UIWindow with UIWindowLevelStatusBar Rotation issue

﹥>﹥吖頭↗ 提交于 2019-11-28 14:19:14

In your UIWindow subclass' init method, observe this notification:

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

self.baseT = self.transform;

Then the method itself:

- (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;
    }
}

Depending on your implementation, you may have to also ensure the frame doesn't change. Also, in the Class' dealloc method, stop listening to the notifications.

As a modification to @dezinezync's answer: performing the rotation would work better if you put it in the willRotateToInterfaceOrientation method of the view controller. This way, the rotation will only be applied if the device is rotated to one of the supported orientations specified in the General -> Deployment Info section of the app's build settings. As an added bonus, you get access to the duration of the rotation animation. Just make sure you have a reference to your modal window in the view controller.

The UIDeviceOrientationDidChangeNotification notification is fired whenever the screen orientation changes, regardless of what orientations are supported. This can lead to undesireable behavior.

Here's an example:

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;
    }
}

I just did something like this on a landscape-only app, and I finally got it working properly by moving everything to the willRotateToInterfaceOrientation method.

Solution for iOS8 (need a transform as showed above as well):

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

However it does not work for iOS9 beta.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!