如何使用核心动画创建导航控制器推送效果?
Posted
技术标签:
【中文标题】如何使用核心动画创建导航控制器推送效果?【英文标题】:how to create navigation controller push effect using core animation? 【发布时间】:2010-01-04 13:44:15 【问题描述】:我正在创建一个应用程序,我想实现推送效果,但不使用导航控制器。有人知道实现此目的的核心动画源代码吗?我有一个像这样的视图层次结构。主控制器上有一个带有 4 个按钮的标题图像。我的意思是无论屏幕前面的视图是什么,它都会一直显示。所以我使用添加子视图方法。现在在一些视图中我想在单击表格视图单元格时进一步导航,但无法弄清楚如何实现该导航动画?
这里是添加子视图的代码......
-(IBAction)ShowDashBoardContentView
if(ButtonDashBoard.selected==YES)
[ButtonDashBoard setSelected:YES];
else
[ButtonDashBoard setSelected:YES];
[ButtonFreebies setSelected:NO];
[self.FreebiesViewMainObject.view removeFromSuperview];
[ButtonConnect setSelected:NO];
[self.ConnectContentViewObject.view removeFromSuperview];
[ButtonDeals setSelected:NO];
[self.DealsViewMainObject.view removeFromSuperview];
if(DashBoardContentView==nil)
DashBoardContent *vController =[[DashBoardContent alloc] initWithNibName:@"DashBoardContent" bundle:[NSBundle mainBundle]];
vController.view.frame=CGRectMake(0, 90, 320, 370);
self.DashBoardContentView=vController;
[vController release];
[self.DashBoardContentView viewWillAppear:YES];
[self.view addSubview:[self.DashBoardContentView view]];
[self BringSubviewsToFront];
-(IBAction)ShowConnectContentView
if(ButtonConnect.selected==YES)
[ButtonConnect setSelected:YES];
else
[ButtonConnect setSelected:YES];
[ButtonFreebies setSelected:NO];
[self.FreebiesViewMainObject.view removeFromSuperview];
[ButtonDashBoard setSelected:NO];
[self.DashBoardContentView.view removeFromSuperview];
[ButtonDeals setSelected:NO];
[self.DealsViewMainObject.view removeFromSuperview];
if(ConnectContentViewObject==nil)
ConnectContentView *vController =[[ConnectContentView alloc] initWithNibName:@"ConnectContentView" bundle:[NSBundle mainBundle]];
vController.view.frame=CGRectMake(0, 90, 320, 370);
self.ConnectContentViewObject=vController;
[vController release];
[self.ConnectContentViewObject viewWillAppear:YES];
[self.view addSubview:[self.ConnectContentViewObject view]];
[self BringSubviewsToFront];
-(IBAction)ShowDealsView
if(ButtonDeals.selected==YES)
[ButtonDeals setSelected:YES];
else
[ButtonDeals setSelected:YES];
[ButtonFreebies setSelected:NO];
[self.FreebiesViewMainObject.view removeFromSuperview];
[ButtonDashBoard setSelected:NO];
[self.DashBoardContentView.view removeFromSuperview];
[ButtonConnect setSelected:NO];
[self.ConnectContentViewObject.view removeFromSuperview];
if(DealsViewMainObject==nil)
DealsViewMain *vController =[[DealsViewMain alloc] initWithNibName:@"DealsViewMain" bundle:[NSBundle mainBundle]];
vController.view.frame=CGRectMake(0, 90, 320, 370);
self.DealsViewMainObject=vController;
[vController release];
[self.DealsViewMainObject viewWillAppear:YES];
[self.view addSubview:[self.DealsViewMainObject view]];
[self BringSubviewsToFront];
-(IBAction)ShowFreebiesView
if(ButtonFreebies.selected==YES)
[ButtonFreebies setSelected:YES];
else
[ButtonFreebies setSelected:YES];
[ButtonDeals setSelected:NO];
[self.DealsViewMainObject.view removeFromSuperview];
[ButtonDashBoard setSelected:NO];
[self.DashBoardContentView.view removeFromSuperview];
[ButtonConnect setSelected:NO];
[self.ConnectContentViewObject.view removeFromSuperview];
if(FreebiesViewMainObject==nil)
FreebiesViewMain *vController =[[FreebiesViewMain alloc] initWithNibName:@"FreebiesViewMain" bundle:[NSBundle mainBundle]];
vController.view.frame=CGRectMake(0, 90, 320, 370);
self.FreebiesViewMainObject=vController;
[vController release];
[self.FreebiesViewMainObject viewWillAppear:YES];
[self.view addSubview:[self.FreebiesViewMainObject view]];
[self BringSubviewsToFront];
-(void)BringSubviewsToFront
[self.view bringSubviewToFront:HeaderView];
[self.view bringSubviewToFront:ButtonDeals];
[self.view bringSubviewToFront:ButtonDashBoard];
[self.view bringSubviewToFront:ButtonConnect];
[self.view bringSubviewToFront:ButtonFreebies];
现在 DealsViewMainObject 包含一个表格视图,我需要从这里进一步导航。同时从超级视图中删除视图如何像 popviewcontroller 动画一样进行动画处理? 顺便说一句,感谢 Felixyz 的回答。
【问题讨论】:
【参考方案1】:您可以按照以下方式使用 CATransition:
// Get index of view to be removed (oldSubView)
NSUInteger index;
for(index = 0; [subViews objectAtIndex:index] != oldSubView; ++index)
// Remove old view
[oldSubView removeFromSuperview];
// Inser new view at right index
[self insertSubview:newSubView atIndex:index];
// Create the transition
CATransition *animation = [CATransition animation];
[animation setDelegate:self];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromLeft;];
[animation setDuration:0.5f];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[[self layer] addAnimation:animation forKey:@"pushIn"];
您不必告诉转换要推送哪些视图,它会自动执行(因为您删除和插入了视图)。
看看这个来自 Apple 的示例代码:how to perform transitions between two views using built-in Core Animation transitions。
编辑(响应 cmets): 此代码应在 UIView 子类中使用。如果你想在 UIViewController 子类中使用它,你必须在任何地方将 self 更改为 self.view。您只需将此代码放入具有如下签名的单独方法中:
-(void)replaceView:(UIView*)oldSubView withView:(UIView*)newSubView;
您将该方法放入您的类中,并在您想用另一个视图替换一个视图时调用它。显然,您需要参考这些观点。
我最好的猜测是你应该替换这段代码:
[self.view addSubview:[self.FreebiesViewMainObject view]];
[self BringSubviewsToFront];
与
[self replaceView:self.rootView withView:freebiesViewMainObject.view];
但是您必须在这方面做更多的工作才能使所有部分组合在一起。真的,看看一些像我链接到的很好的示例代码,并真正理解它,比从 SO 中获取一些代码 sn-ps 并尝试将它们扔到你的代码。
【讨论】:
循环中的子视图是什么? 如何让 oldsubview 删除? 我正在发布我的代码以添加子视图。请在该代码中告诉我我将您的代码放在哪里? 我更新了答案。按照惯例,请注意变量名不应以大写字母开头。您应该使用:headerView、buttonDeals、buttonDashBoard、buttonConnect 等。方法名称也是如此:BringSubviewsToFront 应该是 BringSubviewsToFront。【参考方案2】:无论如何,您都可以使用 UINavigationController,将其属性 navigationBarHidden 设置为 YES,并使用自定义 UIView 调用 pushViewController:animated: 和 popViewControllerAnimated: 或 popToRootViewControllerAnimated: 来驱动动画。
如果你唯一想要的是滑入和滑出动画,我认为这会更容易编写。
【讨论】:
以上是关于如何使用核心动画创建导航控制器推送效果?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不使用导航控制器的情况下推送 UIViewController?
在导航推送上激活没有动画的 UISearchController