transitionFromViewController只是iOS中的一种便捷方法吗?

时间:2012-11-16 23:49:49

标签: iphone ios ios5 uiviewcontroller

我不确定我理解transitionFromViewController:toViewController:duration:options:animation:completion:到底是做什么的。这只是一种方便的方法吗?

例如,这样做有什么不同......

[self transitionFromViewController:fromViewController
                  toViewController:toViewController
                          duration:0.25
                           options:UIViewAnimationOptionCurveEaseInOut
                        animations:^{
                            fromViewController.view.alpha = 0;
                            toViewController.view.alpha = 1;
                        } completion:^(BOOL finished) {
                            [fromViewController removeFromParentViewController];
                            [toViewController didMoveToParentViewController:self];
                        }];

......还有这个?

[self.view addSubview:toViewController.view];
[UIView animateWithDuration:0.25
                      delay:0
                    options:UIViewAnimationOptionCurveEaseOut
                 animations:^{
                     fromViewController.view.alpha = 0;
                     toViewController.view.alpha = 1;
                 } completion:^(BOOL finished){
                     [fromViewController.view removeFromSuperview];
                     [fromViewController removeFromParentViewController];
                     [toViewController didMoveToParentViewController:self];
                 }];

我问的原因是在某些情况下我需要将子控制器视图添加到容器控制器视图的特定子视图中。使用transitionFromViewController:toViewController:duration:options:animation:completion:不会给我这个选项。

3 个答案:

答案 0 :(得分:15)

是的,我认为你是对的:它们在功能上似乎是相同的(不确定我们可以在不知道实现细节的情况下将其称为便捷方法,但很可能)。显然,transitionFromViewController是为视图控制器包含而设计的,animateWithDuration是一个通用的视图动画。

鉴于您显然正在进行遏制,可能应该使用transitionFromViewController而不是animateWithDuration。它是明确的和技术recommended by Apple。如果您在子视图中有fromViewController.view,则新toViewController.view将添加到同一子视图中。

我还建议包括丢失的willMoveToParentViewControlleraddChildViewController(我假设您为了简洁而省略了,但为了完整起见,我将其包括在内):

[fromViewController willMoveToParentViewController:nil];
[self addChildViewController:toViewController];

[self transitionFromViewController:fromViewController
                  toViewController:toViewController
                          duration:0.25
                           options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionTransitionCrossDissolve
                        animations:^{}
                        completion:^(BOOL finished){
                            [fromViewController removeFromParentViewController];
                            [toViewController didMoveToParentViewController:self];
                        }];

另请注意,我正在使用UIViewAnimationOptionTransitionCrossDissolve。如果您手动设置字母,请不要忘记初始化toViewController.view.alpha,例如:

[fromViewController willMoveToParentViewController:nil];
[self addChildViewController:toViewController];
toViewController.view.alpha = 0.0;

[self transitionFromViewController:fromViewController
                  toViewController:toViewController
                          duration:0.25
                           options:UIViewAnimationOptionCurveEaseInOut
                        animations:{
                            fromViewController.view.alpha = 0.0;
                            toViewController.view.alpha = 1.0;
                        }
                        completion:^(BOOL finished){
                            [fromViewController removeFromParentViewController];
                            [toViewController didMoveToParentViewController:self];
                        }];

答案 1 :(得分:1)

简短回答
不,它不仅仅是一种方便的方法,因为在两个子控制器上调用外观方法的时间是不同的。

答案很长
关于 - >

[self.view addSubview:toViewController.view];
[UIView animateWithDuration:0.25
                      delay:0
                    options:UIViewAnimationOptionCurveEaseOut
                 animations:^{
                     fromViewController.view.alpha = 0;
                     toViewController.view.alpha = 1;
                 } completion:^(BOOL finished){
                     [fromViewController.view removeFromSuperview];
                     [fromViewController removeFromParentViewController];
                     [toViewController didMoveToParentViewController:self];
                 }];

当您致电

时,幕后会发生什么
[self.view addSubview:toViewController.view];

是这样的(当然这不完整)

[toViewController.view viewWillAppear:false]; <-- meaning not animated
//Add the view to the view hierarchy
//Layout the view
[toViewController.view viewDidAppear:false]; <-- meaning not animated

之后当你做动画toViewController&#34;认为&#34;它的视图已经可见并且在没有动画的情况下呈现。 fromViewController也是如此。在动画期间,fromViewController不知道它的视图被解散,因为在动画之后调用viewWill / DidDisappear并调用

[fromViewController.view removeFromSuperview];


另一方面 - &gt;

[self transitionFromViewController:fromViewController
              toViewController:toViewController
                      duration:0.25
                       options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionTransitionCrossDissolve
                    animations:^{}
                    completion:^(BOOL finished){
                        [fromViewController removeFromParentViewController];
                        [toViewController didMoveToParentViewController:self];
                    }];

做类似的事

[UIView animateWithDuration:yourDuration
                      delay:yourDelay
                    options:yourOptions
                 animations:^{
                     [toViewController viewWillAppear:true];
                     [fromViewController viewWillDisappear:true];
                     //Add toViewcontroller.view to the view hierarchy
                     //Layout the toViewcontroller.view --> changes here are not animated. (There is no "previous state" as the view has just been added to the hierarchy)
                     //Call your animation-block
                 } completion:^(BOOL finished){
                     [toViewController viewDidAppear:true];
                     [fromViewController.view removeFromSuperview];
                     [fromViewController viewDidDisappear:true];
                     //Call your completion-block
                 }];

如此长的回答
viewWillAppear和viewWillDisappear在animation-block中调用并传递true。这可能对您的应用程序有用,也可能没有用,因此两种方法之间可能存在差异,也可能没有差异。

答案 2 :(得分:0)

正如文档所说,它旨在用于在两个子视图控制器之间进行转换,而不是同一子视图控制器的两个视图。

在您的第一个代码段中,您传递的是与前两个参数相同的toViewController。这是两个不同的视图控制器,而不是同一个。

如果您只是切换相同视图控制器的视图,那么您的第二个示例更合适。