9

我不确定我到底明白了什么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:没有给我这个选项。

4

3 回答 3

16

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

鉴于您显然在进行遏制,因此可能应该使用transitionFromViewController而不是animateWithDuration. 这是明确的,也是Apple 推荐的技术。如果您fromViewController.view在子视图中有 ,新的toViewController.view将被添加到同一个子视图中。

我还建议包括缺少的willMoveToParentViewControllerand addChildViewController(为了简洁起见,我假设你省略了,但为了完整起见,我包括在内):

[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. 如果您手动设置 alphas,请不要忘记初始化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];
                        }];
于 2012-11-17T03:06:21.647 回答
3

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

长答案
关于-->

[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 “认为”它的视图已经可见并且没有动画呈现。fromViewController 也是如此。在动画期间,fromViewController 不知道它的视图被解除,因为 viewWill/DidDisappear 将在动画之后调用

[fromViewController.view removeFromSuperview];


另一方面——>

[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 在动画块内被调用并被传递为真。这对您的应用程序可能有用也可能没有用,因此这两种方法之间可能存在差异,也可能没有差异。

于 2015-03-14T12:26:40.497 回答
0

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

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

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

于 2012-11-16T23:53:33.887 回答