Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper usage of transitionFromViewController:toViewController:duration:options:animations:completion:

I can't seem to find a good example on how to use transitionFromViewController:toViewController:duration:options:animations:completion: properly.

Is this correct? (assuming I want to swap a VC with another)

// Assume fromVC and toVC view controllers are defined and fromVC is already added as a child view controller
[self addChildViewController:toVC];

[self transitionFromViewController:fromVC toViewController:toVC duration:0.3 options:UIViewAnimationOptionTransitionCrossDissolve animations:NULL completion:^(BOOL finished) {
    [fromVC willMoveToParentViewController:nil];
    [fromVC removeFromParentViewController];
    [toVC didMoveToParentViewController:self];
}];

The documentation isn't that clear about when to call what:

The addChildViewController: method calls the willMoveToParentViewController: method of the view controller to be added as a child before adding it, but it does not call the didMoveToParentViewController: method. The container view controller class must call the didMoveToParentViewController: of the child view controller after the transition to the new child is complete or, if there is no transition, immediately after calling the addChildViewController: method.

Likewise, it is is the responsibility of the container view controller to call the willMoveToParentViewController: method before calling the removeFromParentViewController: method. The removeFromParentViewController: method calls the didMoveToParentViewController: method of the child view controller.

Another thing is, how do you use the animations block in this case? Notice in the above code I just put NULL. (I am familiar with block per se, I am just not sure what to put exactly in this one)

like image 912
pixelfreak Avatar asked Dec 10 '11 01:12

pixelfreak


1 Answers

I've implemented this sort of thing similarly in the past. But, I would move -willMoveToParentViewController: outside the completion block since that view controller should be notified before it gets moved (i.e., by the time the completion block has run, fromVC has already had its parent VC set to nil. So all in all, something like this:

[self addChildViewController:toVC];
[fromVC willMoveToParentViewController:nil];

[self transitionFromViewController:fromVC toViewController:toVC duration:0.3 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{} completion:^(BOOL finished) {
    [fromVC removeFromParentViewController];
    [toVC didMoveToParentViewController:self];
}];

In terms of animations, you should never set this parameter to NULL, according to the method documentation. If you have no view properties you want to animate, then you can simply pass it an empty block ^{}. Basically this parameter is used for animating properties of your views in your view hierarchy during the transition. The list of animatable properties can be found in the UIView documentation under the "Animations" heading. As an example, say you don't want your whole view handled by fromVC to cross dissolve, but only want one subview in its view hierarchy named subview1 to fade out. You can do this using the animations block:

[self addChildViewController:toVC];
[fromVC willMoveToParentViewController:nil];

[self transitionFromViewController:fromVC 
                  toViewController:toVC
                          duration:0.3
                           options:UIViewAnimationOptionTransitionNone
                        animations:^{
                                       [subview1 setAlpha:0.0];
                                   }
                        completion:^(BOOL finished) {
                                       [fromVC removeFromParentViewController];
                                       [toVC didMoveToParentViewController:self];
                                   }];
like image 131
Sean Avatar answered Oct 21 '22 14:10

Sean