如何使用核心动画创建导航控制器推送效果?

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

如何使用重叠的透明视图控制器重新创建 FaceTime 的导航视图控制器过渡动画?

如何正确地动画推送带有透明导航栏和工具栏的视图控制器?

嵌套推送动画可能导致导航栏损坏多次警告