当前位置:  开发笔记 > IOS > 正文

如何从UINavigationController弹出视图并在一次操作中将其替换为另一个视图?

如何解决《如何从UINavigationController弹出视图并在一次操作中将其替换为另一个视图?》经验,为你挑选了4个好方法。

我有一个应用程序,我需要从UINavigationController的堆栈中删除一个视图,并将其替换为另一个.情况是第一个视图创建一个可编辑的项目,然后用该项目的编辑器替换它自己.当我在第一个视图中执行明显的解决方案时:

MyEditViewController *mevc = [[MYEditViewController alloc] initWithGizmo: gizmo];

[self retain];
[self.navigationController popViewControllerAnimated: NO];
[self.navigationController pushViewController: mevc animated: YES];
[self release];

我的行为非常奇怪.通常编辑器视图会出现,但如果我尝试使用导航栏上的后退按钮,我会得到额外的屏幕,有些空白,有些只是搞砸了.标题也变得随机.就像导航堆栈完全被冲洗一样.

什么是解决这个问题的更好方法?

谢谢,马特



1> Alex Wayne..:

我发现你根本不需要手动搞乱这个viewControllers属性.基本上有两个棘手的事情.

    self.navigationControllernil如果self当前不在导航控制器的堆栈上,将返回.因此,在失去对它的访问权限之前将其保存到本地变量.

    您必须retain(并且正确地release)self或拥有您所使用的方法的对象将被取消分配,从而导致陌生.

一旦你做了准备,然后像往常一样弹出和推动.此代码将立即用另一个替换顶部控制器.

// locally store the navigation controller since
// self.navigationController will be nil once we are popped
UINavigationController *navController = self.navigationController;

// retain ourselves so that the controller will still exist once it's popped off
[[self retain] autorelease];

// Pop this controller and replace with another
[navController popViewControllerAnimated:NO];
[navController pushViewController:someViewController animated:NO];

在最后一行中,如果您更改animatedYES,则新屏幕实际上将进行动画处理,您刚刚弹出的控制器将动画显示.看起来很漂亮!


只需移除保留/自动释放行,就可以很好地使用ARC.
也许是一个明显的补充,但是你可以将上面的代码放在一个动画块中来设置过渡动画:[UIView beginAnimations:@"View Flip"context:nil]; [UIView setAnimationDuration:0.80]; [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:navController.view cache:NO]; [navController pushViewController:newController animated:YES]; [UIView commitAnimations];
@TomerPeled是的,这个答案将近5年......我认为就像iOS 3一样.API已经发生了很大变化,我不确定它是不是最好的答案了.

2> Luke Rogers..:

以下方法对我来说似乎更好,也适用于ARC:

UIViewController *newVC = [[UIViewController alloc] init];
// Replace the current view controller
NSMutableArray *viewControllers = [NSMutableArray arrayWithArray:[[self navigationController] viewControllers]];
[viewControllers removeLastObject];
[viewControllers addObject:newVC];
[[self navigationController] setViewControllers:viewControllers animated:YES];



3> Lily Ballard..:

根据经验,您将不得不直接摆弄UINavigationController的viewControllers属性.这样的事情应该有效:

MyEditViewController *mevc = [[MYEditViewController alloc] initWithGizmo: gizmo];

[[self retain] autorelease];
NSMutableArray *controllers = [[self.navigationController.viewControllers mutableCopy] autorelease];
[controllers removeLastObject];
self.navigationController.viewControllers = controllers;
[self.navigationController pushViewController:mevc animated: YES];

注意:我将保留/释放更改为保留/自动释放,因为它通常更强大 - 如果保留/释放之间发生异常,您将泄漏自己,但自动释放负责处理.



4> 小智..:

经过很多努力(并调整了Kevin的代码),我终于想出了如何在从堆栈中弹出的视图控制器中执行此操作.我遇到的问题是我从控制器数组中删除了最后一个对象后,self.navigationController返回nil.我认为这是由于UIViewController文档中的这一行在实例方法navigationController上"如果视图控制器在其堆栈中,则仅返回导航控制器".

我认为一旦从堆栈中删除当前视图控制器,其navigationController方法将返回nil.

以下是调整后的代码:

UINavigationController *navController = self.navigationController;
MyEditViewController *mevc = [[MYEditViewController alloc] initWithGizmo: gizmo];

NSMutableArray *controllers = [[self.navigationController.viewControllers mutableCopy] autorelease];
[controllers removeLastObject];
navController.viewControllers = controllers;
[navController pushViewController:mevc animated: YES];

推荐阅读
依然-狠幸福
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有