Animated transition doesn't work correctly in

2019-02-06 22:43发布

问题:

My app only supports the landscape right orientation.

I'm trying to transition into a view controller's view, but when it performs the transition animation (such as curl up), the view is rotated 90 degrees (so, the simulator is still in landscape-right orientation, but the view appears rotated by 90 degrees). When the transition finishes it rotates to the correct orientation. My code is below.

- (IBAction)buttonTouched
{
    MyViewController *aViewController = [[MyViewController alloc] initWithNibName:NSStringFromClass([MyViewController class]) bundle:nil];

    [UIView transitionFromView:self.view 
                        toView:aViewController.view 
                      duration:2 
                       options:UIViewAnimationOptionTransitionCurlUp 
                    completion:NULL];
}

It appears as though the view doesn't get the "orientation changed" notification, so it presents it in portrait, and then changes to landscape after the animation finishes. I have set it up in IB so that it is all laid out in landscape.

EDIT: I also tried adding a View Controller to self's IB file and transitioning to that view (thinking maybe it was too close between the initialization and the transition) but the same thing happened.

回答1:

Well, the main reason is that self.view (which currently "knows" that you're in landscape) is being replaced with a new view which doesn't have that information. So one thought is to just put aViewController.view as a subView of self.view (assuming that aViewController is opaque). Ah, you say, but then I lose the nice animation of transitionFromView. Well, try this niceness:

[UIView transitionWithView:self.view
                  duration:2 
                   options:UIViewAnimationOptionTransitionCurlUp
                animations:^{
                    [self.view addSubview:aViewController.view];
                } 
                completion:NULL];

If for some reason that doesn't work for you, the alternative is to "teach" aViewController.view that it's really a landscape view:

#define DEGREES_TO_RADIANS(__ANGLE__) ((__ANGLE__) / 180.0 * M_PI)
-(void)setNewViewToLandscape:(UIView*)viewObject {
     //assumes self.view is landscape and viewObject is portrait
     [viewObject setCenter:CGPointMake( self.view.frame.size.width/2,self.view.frame.size.height/2)];
     CGAffineTransform cgCTM = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(90));
     viewObject.transform = cgCTM;
     viewObject.bounds = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
}

 MyViewController *aViewController = [[MyViewController alloc] initWithNibName:NSStringFromClass([MyViewController class]) bundle:nil];
[self setNewViewToLandscape:aViewController.view];

[UIView transitionFromView:self.view 
                    toView:aViewController.view 
                  duration:2 
                   options:UIViewAnimationOptionTransitionCurlUp 
                completion:NULL];

One minor additional point is that your aViewController is leaking, so you should make it a retained property of the parent viewController.