如何使用淡出动画关闭模态VC?

17
我在我的展示视图控制器中使用以下代码来淡入子模态视图控制器,这很好用:
self.infoViewController.view.alpha = 0.0;
[self.navigationController presentModalViewController:self.infoViewController animated:NO];
[UIView animateWithDuration:0.5
             animations:^{self.infoViewController.view.alpha = 1.0;}];

但我无法将其淡出,我尝试了几件事情,这是我最新的尝试,但它不起作用:

- (IBAction)dismissAction:(id)sender
{
if ([[self parentViewController] respondsToSelector:@selector(dismissModalViewControllerAnimated:)])
{
    [[self parentViewController] dismissModalViewControllerAnimated:YES];
    self.parentViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
    self.parentViewController.view.alpha = 0.0;
    [UIView animateWithDuration:0.5
                     animations:^{self.parentViewController.view.alpha  = 1.0;}];
} else 
{
    [[self presentingViewController] dismissViewControllerAnimated:YES completion:nil];
    self.presentedViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
    self.presentedViewController.view.alpha = 0.0;
    [UIView animateWithDuration:0.5
                     animations:^{
                         self.presentedViewController.view.alpha  = 1.0;}];
}

模态视图控制器会立即淡出,而不像显示时那样在一段时间内逐渐淡出。


如果您希望此代码在iOS 5之前的设备上运行,您需要保护对presentedViewControllerdismissModalViewControllerAnimated方法的调用。 - smparkes
如果你看到一个解散的动画,那肯定意味着这段代码正在被执行,并且通过另一种方法进行了解散。 - smparkes
3个回答

51

这部分(原始部分)并不是要削弱H2CO3的正确答案。 UIModalTransitionStyleCrossDissolve基本上就是你要寻找的效果。你只是在太晚之前没有设置modalTransitionStyle。用以下函数替换所有代码:

-(void)show{
    self.infoViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
    [self presentModalViewController:self.infoViewController animated:YES];
}
- (IBAction)dismissAction:(id)sender{
    [self dismissModalViewControllerAnimated:YES];
}

针对时间问题的编辑: 让我们来谈论一下有问题的代码。我们将集中讨论 if true 部分,因为它与 else 部分基本相同。

[[self parentViewController] dismissModalViewControllerAnimated:YES];
self.parentViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
self.parentViewController.view.alpha = 0.0;
[UIView animateWithDuration:0.5
                 animations:^{self.parentViewController.view.alpha  = 1.0;}];

如果您正在寻找一种相互动画,那么这不是它。在原始动画中,您将下一个视图的alpha设置为0,然后呈现下一个视图控制器,接着将其视图的alpha设置为1。因此,逻辑上您需要在动画之后关闭视图控制器;使用块非常容易实现。代码可能如下所示:

[UIView animateWithDuration:0.5 animations:^{
    self.view.alpha = 0;
} completion:^(BOOL b){
    [self.presentingViewController dismissModalViewControllerAnimated:NO];
    self.view.alpha = 1;
}];

这行代码将视图的透明度动画到0,然后(完成后)关闭呈现的视图控制器,并将视图的透明度恢复为1。这是一种互补的动画效果。


谢谢,但是你和H2CO3都忽略了我的代码中有一个withDuration部分。在简化的代码中,没有办法设置淡入/淡出所需的时间长度。而且我发布的帖子中写道:“..但不是在一段时间内”。对不起,我的标题可能应该说如何实现淡出并控制其持续时间,但我认为从发布的代码和描述中这一点很明显,如果没有,对不起。 - Gruntcakes
Edited in response to comment - NJones
4
在iOS8中,似乎需要在presentingViewController上添加self.modalTransitionStyle = UIModalTransitionStyleCrossDissolve,这样dismiss也会是CrossDissolve。 - Matej Ukmar

11
在UIViewController的文档中,我们可以找到:
@property(nonatomic, assign) UIModalTransitionStyle modalTransitionStyle

将此属性设置为UIModalTransitionStyleCrossDissolve,它将正确地溶解 :) 希望这有所帮助。

谢谢,它会消失,但是它会立即消失,而我在它出现时有一个0.5秒的动画。我怎样才能让它慢慢消失? - Gruntcakes
[self.parentViewController dismissModalViewControllerAnimated:YES];[self.parentViewController dismissModalViewControllerAnimated:YES]; - user529758
将“Animated”属性设置为YES时,它会滚动退出,将“Animated”属性设置为NO时,它会溶解消失,但仍然立即执行。我已经在上面的编辑中发布了我的最新代码。 - Gruntcakes
将此标记为已接受,因为它回答了我的问题标题,尽管我仍在寻找有关如何实现具有设置持续时间的淡入淡出效果的答案。 - Gruntcakes

0

我猜这对那些仍然试图在全屏模式下使用MPMoviePlayerViewController并且方向与应用程序主要方向不同的英雄人物可能会有所帮助。

我花了半天时间尝试以模态或非模态方式呈现MPMoviePlayerViewController,但是在转换动画方面没有任何运气。(模态模式需要设置与应用程序主要方向不同的方向)。

我尝试了presentViewController或presentModalViewController,但结果都一样。无论modalTransitionStyle属性设置为何种类型,如果我执行[... dismissViewControllerAnimated:true ...],则默认的转换样式(UIModalTransitionStyleCoverVertical)仍然会被使用。我在iOS 5.1设备和iOS 6模拟器中进行了测试。

我还没有尝试过其他类型的控制器...考虑到常见控制器具有dismissMoviePlayerViewControllerAnimated方法,我可以假设无论视频控制器如何出现,该方法都会被使用来解除控制器。(进入转换对我也没有用,除非它们没有处理为CoverVertical(在模态转换样式更改的情况下)。

所以,我的解决方案是根本不使用过渡动画。 我相信,苹果为MovieViewController只允许一些明确的动画有一些原因(我真的希望如此,并且这不是因为“懒惰”),但如果他们想要一些好的用户体验,他们失败了,因为在我的应用程序中,当视频没有任何动画时甚至更好(这肯定比CrossDisolving更糟),但这比平凡的CoverVertical更好。

从开发者的角度来看,这听起来确实像是他们花费了更多的钱请设计师为客户绘制漂亮的图标,而不是开发人员更愉快和有效的工作。(


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接