iOS 8 / 7 UIWindow with UIWindowLevelStatusBar Rotation issue

前端 未结 3 1754
眼角桃花
眼角桃花 2020-12-12 01:41

I\'m trying to add a UIWindow with UIWindowLevelStatusBar level. it works in portrait mode on ipad perfectly but after rotating device its messed up.

on

相关标签:
3条回答
  • 2020-12-12 01:57

    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.

    0 讨论(0)
  • 2020-12-12 02:03

    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.

    0 讨论(0)
  • 2020-12-12 02:10

    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.

    0 讨论(0)
提交回复
热议问题