2011-04-29 66 views
4

我已经找到方法来调用pushViewController缩放动画, 像facebook应用程序主菜单图标点击动画。 (新viewController从中心弹出,并且它缩放到原始大小。)pushViewController带缩放动画,显示背景

我搜索了几种方法来改变pushViewController的动画。

首先,我想这一点:

viewController.view.transform = CGAffineTransformMakeScale(0.5f, 0.5f); 
[UIView animateWithDuration:0.5f animations:^{ 
    viewController.view.transform = CGAffineTransformMakeScale(1.0f, 1.0f); 
}]; 
[self.navigationController pushViewController:viewController animated:NO]; 

但有问题,当动画开始,这里只有白色背景 旧的viewController消失。

如果我使用CATransition改变动画, 我可以同时显示老&新的viewController两者 但没有缩放动画,只有在移动,推,淡入动画。

我想显示新的&旧的视图控制器像CATransition动画, ,并需要实现我的自定义动画的方式。

这是我的最后一个建议,肮脏的方式:

[self.view addSubview:viewController.view]; 
viewController.view.transform = CGAffineTransformMakeScale(0.5f, 0.5f); 
[UIView animateWithDuration:0.5f 
         delay:0.0f 
        options:UIViewAnimationCurveEaseInOut 
       animations:^{ 
    viewController.view.alpha = 1.0f; 
    viewController.view.transform = CGAffineTransformMakeScale(1.0f, 1.0f); 
} completion:^(BOOL finished) { 
    [self.navigationController pushViewController:viewController animated:NO]; 
    [viewController release]; 
}]; 

首先,我增加了新的viewController.view作为子视图,我可以给新老&观看动画两者。 动画结束后,再pushViewController。

这样我可以实现我的想法, 但我认为这是肮脏的方式,而且也仍然问题:

导航栏项目不会立即改变,这是动画结束后改变。

有没有简单明了的方法来实现这个动画? 我认为这是不可能的,如果没有改变pushViewController的原始实现,我应该做子类pushViewController?

感谢您的阅读和您的帮助。

回答

2

我不认为动画是用视图控制器完成的。您可以保留现有的视图控制器。创建一个新的应该放大的UIView。将新的UIView添加到现有的视图控制器并对其应用动画。

2

在回答原始问题时,我不确定您是否认为这是一个改进,但我认为您可能能够在正在转换的视图中包含导航栏(a)在IB中添加(b)在开始动画前隐藏根控制器导航栏的动画(以便在新视图滑入时滑动),以及(c)在您的完成块中您的动画,隐藏新视图的添加导航栏并取消隐藏根控制器的导航栏。也许这会让你更接近你想要的东西,尽管可能与你最初设想的不同。不过这并不完美。该代码,可能看起来像:

MyViewController *newController = [[MyViewController alloc] initWithNibName:@"MyView" bundle:nil]; 
newController.view.transform = CGAffineTransformMakeScale(0.1f, 0.1f); 
[self.navigationController setNavigationBarHidden:YES animated:YES]; 
[self.view addSubview:newController.view]; 

[UIView animateWithDuration:0.5f 
         delay:0.0f 
        options:UIViewAnimationCurveEaseInOut 
       animations:^{ 
        newController.view.alpha = 1.0f; 
        newController.view.transform = CGAffineTransformMakeScale(1.0f, 1.0f); 
       } completion:^(BOOL finished) { 
        [newController.view removeFromSuperview]; 
        [self.navigationController pushViewController:newController animated:NO]; 
        [newController.tempBar setHidden:YES]; 
        [self.navigationController setNavigationBarHidden:NO animated:NO]; 
       }]; 

它加入少许更多“猛料”你的“肮脏的方式”,但它可能会渲染你要找的效果。您只是想让新视图中的临时导航栏看起来与最终的根控制器导航栏的外观很相似,并且用户不应该更聪明。如果这仍然不能完全实现您要查找的内容,那么您可以完全隐藏根控制控制器的栏,并始终将自己的导航放在视图上,在这种情况下,转换到您的视图时效果将完全无缝新视图。

或者,您可以使用您现有的代码,并在转换之前设置当前视图的标题,这样可能看起来像标题更改发生在前面。但是,当你返回时,你可能不得不做些重设它的事情,设置后退按钮等等,所以它可能不值得。

另一方面,这是一个与原始问题有点切线(所以我提前道歉),但回应另一个建议,你不应该动画视图控制器,而只是视图,我会喜欢发表一个谨慎的话。是的,从技术上讲这是对的,但我很紧张这是否会鼓励人们采取不好的做法来增加新的视图:(a)创建一个新的视图控制器; (b)将该视图控制器视图的添加动画化为当前视图的子视图;但是(c)不会对新视图控制器做任何事情来将其添加到视图控制器层次结构中(例如pushViewController或presentViewController)。

如果这是其他答案的意图,我不得不说,我认为这是一个非常糟糕的想法。 (如果这不是想要的结果,那么我道歉,但我认为这是容易被人误解的建议。)底线,我最近看到的人做这样的事情:

MyViewController *newController = [[MyViewController alloc] initWithNibName:@"MyView" bundle:nil]; 

// do some animation around adding the new view as a subview of your current view 
// but neglect to ever invoke pushViewController or presentViewController 

[self.view addSubview:newController.view]; 

这是推荐出于几个原因。首先,如果它是一个ARC项目,当newController超出范围时,您的视图控制器将被丢弃。 (似乎有很多这样的问题在SO上发布,这是因为人们过渡到ARC时出现异常。)当然,你可以通过使newController成为你的主控制器的ivar来解决这个问题,所以它不会掉出来的范围,但要小心记住在主控制器最终被释放或删除子视图时将其设置为零,否则可能发生泄漏。如果你在一个非ARC项目中,它更容易泄漏,所以一定要在子视图被移除时释放视图控制器以防止泄漏。

其次,也许更重要的是,虽然上面的代码似乎工作(或者至少如果你让控制器是一个伊娃),但你最终与你的视图控制器的层次结构和你的意见。 (在session 102 of WWDC 2011关于不同的主题,视图控制器遏制,它包括冗长,但相关的讨论保持视图控制器层次结构和视图层次协调的重要性,例如旋转事件可能无法正确发送到您的新视图的控制器,因为控制器不在控制器层次结构中,因此iOS不会知道将它们发送给您的控制器。)底线,如果您使用其他视图控制器的视图添加为当前视图的子视图,则它很脆弱,易于破坏在iOS升级时,旋转事件等内容不会正确传递到新视图的视图控制器。如果你这样做,至少要意识到这不是一个好的做法,并且你自己要做的风险评估就是你是否想这样做。没有必要绕过适当的视图控制器层次结构,我个人想劝阻倾向于这样做的人。底线,如果您正在转换到不同视图控制器的视图,您确实想要坚持pushViewController或presentViewController,并围绕新控制器的视图执行动画(通常它不像这样复杂动画...通常它非常简单,我已经完成了各种淡入淡出和轻松动画......这是使用这种复杂的转换)。

另一种方法是,如果你想动画一个新的UIView子视图并且根本不处理视图控制器,只要确保它不是另一个视图控制器的视图,而是例如使用相同视图以编程方式创建的视图控制器作为您的始发视图。如果您决定使用另一个视图控制器的视图作为您现有控制器的子视图,只需要知道它有点脆弱,并且有些事件可能不会像您期望的那样传输到您的新视图控制器,并且它可能不是你可能想要的“未来证明”。