Manual Rotation Method Breaks with Side Switch

限于喜欢 提交于 2019-12-11 18:35:56

问题


Currently I'm workign on a drawing app for the iPad. I need to reposition and rotate the toolbar in the app when it is put into a different orientation while keeping the the drawing area in the same place.

I found a method here for doing this. It uses the NSNotificationCenter to monitor for rotation changes. This calls a custom didRotate: method that will rotate and reposition my toolbar based on the UIDeviceOrientation.

This part works fine. However, whenever the side switch on the iPad is engaged to lock the orientation, the toolbar repositions to the location is was at launch.

For example: If I start the application in landscape left and rotate it to portrait, the toolbar will reposition to the bottom of the screen. However as soon as I engage the slide switch, it moves to the side of the screen for the landscape left orientation.

The methods I'm using for this are all below.

- (void)viewDidLoad {
    [super viewDidLoad];


    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didRotate:) name:UIDeviceOrientationDidChangeNotification object:nil];
}

- (void)didRotate:(NSNotification *)notification {
    UIDeviceOrientation deviceOrientation = [[UIDevice currentDevice] orientation];

    UIInterfaceOrientation interfaceOrientation;

    bool orientationFound = YES;

    if (deviceOrientation == UIDeviceOrientationPortrait) {
        interfaceOrientation = UIInterfaceOrientationPortrait;
    } else if (deviceOrientation == UIDeviceOrientationPortraitUpsideDown) {
        interfaceOrientation = UIInterfaceOrientationPortraitUpsideDown;
    } else if (deviceOrientation == UIDeviceOrientationLandscapeLeft) {
        interfaceOrientation = UIInterfaceOrientationLandscapeRight;
    } else if (deviceOrientation == UIDeviceOrientationLandscapeRight) {
        interfaceOrientation = UIInterfaceOrientationLandscapeLeft;
    } else {
        orientationFound = NO;
    }



    if (orientationFound) {
        [self.toolbar changeToOrientation:interfaceOrientation withDuration:.25];
        [self.tutorialOverlay changeToOrientation:interfaceOrientation];
    }
}

- (void)changeToOrientation:(UIInterfaceOrientation)orientation withDuration:(float)duration {
    float angle;
    CGPoint origin;

    if (orientation == UIInterfaceOrientationPortrait) {
        angle = portraitAngle;
        origin = self.portraitOrigin;
    } else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
        angle = portraitUpsideDownAngle;
        origin = self.portraitUpsideDownOrigin;
    } else if (orientation == UIInterfaceOrientationLandscapeLeft) {
        angle = landscapeLeftAngle;
        origin = self.landscapeLeftOrigin;
    } else if (orientation == UIInterfaceOrientationLandscapeRight) {
        angle = landscapeRightAngle;
        origin = self.landscapeRightOrigin;
    }

    [UIView animateWithDuration:duration animations:^{
        self.transform = CGAffineTransformMakeRotation(angle);

        CGRect rect = self.frame;

        rect.origin = origin;

        self.frame = rect;
    }];
}

回答1:


I'd strongly recommend against using this notification-based approach. Note that the name of the notification is UIDeviceOrientationDidChangeNotification; the device orientation is not the same as the interface orientation, and it leads to lots of little issues like this. (The device orientation, for example, includes UIDeviceOrientationFaceDown, which is never associated with an interface orientation.)

I'd suggest letting your view controller automatically rotate itself; this will place the toolbar, etc, for you. You can then override - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration to put the drawing area back to the orientation you want to maintain. (You'd use similar code to your changeToOrientation method above, but for the drawing area instead, and you don't need to create your own animation block. Also, the angles would all be negated, because you're undoing the change the view controller made.)




回答2:


I just answered a similar question here. Basically just allow the interface to rotate, but rotate the view you don't want to rotate 'back' in willRotateToInterfaceOrientation:duration:.



来源:https://stackoverflow.com/questions/8114445/manual-rotation-method-breaks-with-side-switch

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