我在一个视图控制器中有一个项目列表。我可以选择一个项目,然后推送一个详细视图控制器以显示所选项目的详细信息。然后我可以选择编辑按钮(从导航栏中)并按下编辑视图控制器以允许我编辑项目的详细信息。所有这些都有效,包括取消和撤消。
在第一个列表视图控制器中,我还有一个添加按钮(在导航栏中),我可以在其中添加新记录。(这是使用核心数据,但我认为这与我的问题无关。)我通过为项目创建空白记录开始测试,当出现详细视图控制器时,所有字段都是空白的。然后我可以选择编辑按钮并编辑详细信息,就像它是一个已经填充的记录一样。这也有效。
我一直在尝试做的是选择添加按钮并按下详细视图控制器,然后立即按下编辑视图控制器。我想这样做的原因是当我弹出编辑视图控制器时,将显示详细视图控制器。(然后我可以弹回列表视图控制器或再次推入编辑视图控制器。)
我遇到了麻烦。
我在列表视图控制器中尝试了两次推送,如下所示:
- (void) add {
clientInfoTVC.clientMO = [self createNewClient];
[self.navigationController pushViewController:clientInfoTVC animated:YES];
[self.navigationController pushViewController:clientInfoTVC.clientEditTVC animated:YES];
}
其中 clientInfoTVC.clientEditTVC 指向 eidt 视图控制器。当我尝试添加时,这会导致 SIGABRT 错误并停止。
然后,我尝试在选择添加时在详细视图控制器中设置标志属性值,然后在第一次推送之前,然后在详细视图控制器的 viewWillAppear 中进行第二次推送。这出错了。我尝试将第二次推送移动到详细视图控制器的 viewDidAppear,结果相同。
我迷路了。有人可以给我一些想法如何将一个视图控制器推送到第二个视图控制器,以便我可以维护导航堆栈并弹回中间视图控制器吗?
@ljkyser 找到了部分答案。但我还发现,简单地将视图压入堆栈并不能让它执行它的 init、viewWillAppear 和 viewDidLoad。我猜测由于所有这些都发生在主线程上,因此推送视图只是将该视图控制器排队到运行循环中。推送第二个视图控制器会从运行循环中删除第一个视图控制器,并将第二个视图控制器放入运行循环队列中。也许有人可以比我刚刚做的更准确地验证并描述它。
无论如何,要正确初始化编辑视图控制器,我必须向它传递一个指针,以便它可以找到它正在使用的托管对象。我最初从详细视图控制器中实例化了编辑视图控制器。因此,在我的原始代码中,我正在推送一个尚未实例化的视图控制器。为了安全起见,我从列表视图控制器中对其进行了实例化,然后确保在进行双推之前设置了所有托管对象指针,如下所示:
- (void) add {
Client *clientNew = [[NSEntityDescription alloc] init];
clientNew = [self createNewClient];
clientInfoTVC.clientMO = clientNew;
clientEditTVC.clientMO = clientNew;
[clientNew release];
[self.navigationController pushViewController:clientInfoTVC animated:NO];
[self.navigationController pushViewController:clientEditTVC animated:YES];
}
确认@ljkyser 给出的答案,我在保持第一个动画的同时尝试了这些更改:YES。有了这个,导航栏看起来正确,但视图的其余部分不同步。设置动画:NO 解决了这个问题。