Why is UIDeviceOrientationDidChangeNotification not always registered?

I wrote a simple view controller that shows a modal popup dialog. Since it creates a new window to fit the entire screen, I added an observer UIDeviceOrientationDidChangeNotificationthat calculates how to rotate the view using CGAffineTransformMakeRotation(). And it works.

Primarily. The disadvantage is that I can play with orientation and make her stand sideways or upside down. Watch this 18 second video demonstrating the problem. When debugging, it seems that sometimes the notification does not start, or at least does not call the callback method that listens for it.

I must have missed something, because if you look at the video again, you will notice that the view behind it rotates correctly. For this drives -willAnimateRotationToInterfaceOrientation:duration:. Typically, an iOS controller method is always called correctly (presumably controlled by an observer UIDeviceOrientationDidChangeNotificationin a UIViewController), but my own code is not?

+3
source share
3 answers

, UIDeviceOrientationDidChangeNotification. UIViewController . -willAnimateRotationToInterfaceOrientation:duration: . . , UIViewController, , presentModalViewController, , . , UIDeviceOrientationDidChangeNotification . , , .: - (

0

UIApplicationWillChangeStatusBarOrientationNotification Kobo, , , . , , , . , Apple , .

Kobo iPad (UIAlertView - iPad, Richard Penner ). iOS ( IIRC) , UIWindow, .

UIViewController, .

- (void) presentDialogWindow
{
    // register for orientation change notification
    [[NSNotificationCenter defaultCenter] addObserver: self
                                             selector: @selector(orientationWillChange:)
                                                 name: UIApplicationWillChangeStatusBarOrientationNotification
                                               object: nil];
    [[NSNotificationCenter defaultCenter] addObserver: self
                                             selector: @selector(orientationDidChange:)
                                                 name: UIApplicationDidChangeStatusBarOrientationNotification
                                               object: nil];
}

- (void) orientationWillChange: (NSNotification *) note
{
    UIInterfaceOrientation current = [[UIApplication sharedApplication] statusBarOrientation];
    UIInterfaceOrientation orientation = [[[note userInfo] objectForKey: UIApplicationStatusBarOrientationUserInfoKey] integerValue];
    if ( [self shouldAutorotateToInterfaceOrientation: orientation] == NO )
        return;

    if ( current == orientation )
        return;

    // direction and angle
    CGFloat angle = 0.0;
    switch ( current )
    {
        case UIInterfaceOrientationPortrait:
        {
            switch ( orientation )
            {
                case UIInterfaceOrientationPortraitUpsideDown:
                    angle = (CGFloat)M_PI;  // 180.0*M_PI/180.0 == M_PI
                    break;
                case UIInterfaceOrientationLandscapeLeft:
                    angle = (CGFloat)(M_PI*-90.0)/180.0;
                    break;
                case UIInterfaceOrientationLandscapeRight:
                    angle = (CGFloat)(M_PI*90.0)/180.0;
                    break;
                default:
                    return;
            }
            break;
        }
        case UIInterfaceOrientationPortraitUpsideDown:
        {
            switch ( orientation )
            {
                case UIInterfaceOrientationPortrait:
                    angle = (CGFloat)M_PI;  // 180.0*M_PI/180.0 == M_PI
                    break;
                case UIInterfaceOrientationLandscapeLeft:
                    angle = (CGFloat)(M_PI*90.0)/180.0;
                    break;
                case UIInterfaceOrientationLandscapeRight:
                    angle = (CGFloat)(M_PI*-90.0)/180.0;
                    break;
                default:
                    return;
            }
            break;
        }
        case UIInterfaceOrientationLandscapeLeft:
        {
            switch ( orientation )
            {
                case UIInterfaceOrientationLandscapeRight:
                    angle = (CGFloat)M_PI;  // 180.0*M_PI/180.0 == M_PI
                    break;
                case UIInterfaceOrientationPortraitUpsideDown:
                    angle = (CGFloat)(M_PI*-90.0)/180.0;
                    break;
                case UIInterfaceOrientationPortrait:
                    angle = (CGFloat)(M_PI*90.0)/180.0;
                    break;
                default:
                    return;
            }
            break;
        }
        case UIInterfaceOrientationLandscapeRight:
        {
            switch ( orientation )
            {
                case UIInterfaceOrientationLandscapeLeft:
                    angle = (CGFloat)M_PI;  // 180.0*M_PI/180.0 == M_PI
                    break;
                case UIInterfaceOrientationPortrait:
                    angle = (CGFloat)(M_PI*-90.0)/180.0;
                    break;
                case UIInterfaceOrientationPortraitUpsideDown:
                    angle = (CGFloat)(M_PI*90.0)/180.0;
                    break;
                default:
                    return;
            }
            break;
        }
    }

    CGAffineTransform rotation = CGAffineTransformMakeRotation( angle );

    [UIView beginAnimations: @"" context: NULL];
    [UIView setAnimationDuration: 0.4];
    self.view.transform = CGAffineTransformConcat(self.view.transform, rotation);
    [UIView commitAnimations];
}

- (void) orientationDidChange: (NSNotification *) note
{
    UIInterfaceOrientation orientation = [[[note userInfo] objectForKey: UIApplicationStatusBarOrientationUserInfoKey] integerValue];
    if ( [self shouldAutorotateToInterfaceOrientation: [[UIApplication sharedApplication] statusBarOrientation]] == NO )
        return;

    self.view.frame = [[UIScreen mainScreen] applicationFrame];

    [self didRotateFromInterfaceOrientation: orientation];
}

, , , -ModalDialog, :

UIView *window = [[UIApplication sharedApplication] keyWindow];
[window addSubview: theController.view];
[theController presentDialogWindow];

UIViewController, , github. , .

+12

UIDeviceOrientation , UIInterfaceOrientation:

UIDeviceOrientationUnknown,
UIDeviceOrientationFaceUp,              // Device oriented flat, face up
UIDeviceOrientationFaceDown             // Device oriented flat, face down

, , ?

- didRotate .

0

Source: https://habr.com/ru/post/1791106/


All Articles