我有一个应用程序,我需要从UINavigationController的堆栈中删除一个视图,并将其替换为另一个.情况是第一个视图创建一个可编辑的项目,然后用该项目的编辑器替换它自己.当我在第一个视图中执行明显的解决方案时:
MyEditViewController *mevc = [[MYEditViewController alloc] initWithGizmo: gizmo]; [self retain]; [self.navigationController popViewControllerAnimated: NO]; [self.navigationController pushViewController: mevc animated: YES]; [self release];
我的行为非常奇怪.通常编辑器视图会出现,但如果我尝试使用导航栏上的后退按钮,我会得到额外的屏幕,有些空白,有些只是搞砸了.标题也变得随机.就像导航堆栈完全被冲洗一样.
什么是解决这个问题的更好方法?
谢谢,马特
我发现你根本不需要手动搞乱这个viewControllers
属性.基本上有两个棘手的事情.
self.navigationController
nil
如果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];
在最后一行中,如果您更改animated
为YES
,则新屏幕实际上将进行动画处理,您刚刚弹出的控制器将动画显示.看起来很漂亮!
以下方法对我来说似乎更好,也适用于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];
根据经验,您将不得不直接摆弄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];
注意:我将保留/释放更改为保留/自动释放,因为它通常更强大 - 如果保留/释放之间发生异常,您将泄漏自己,但自动释放负责处理.
经过很多努力(并调整了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];