7

一周前我对此有点摸不着头脑,现在有了更多可可经验,我觉得我对可能发生的事情有所了解。

我正在制作一个由 UINavigationController 驱动的应用程序。在 AppDelegate 中,我创建了这个类的一个实例,使用“page 1”作为根视图控制器。

UINavigationController *aNavigationController = [[UINavigationController alloc] 
     initWithRootViewController:page1ViewController];

现在这就是我遇到问题的地方。从“第 1 页”开始,我想使用一个模态视图控制器,它在界面上滑动,然后在用户进行编辑后消失。我在 Page1ViewController 内部使用这样的代码来做到这一点:

[self presentModalViewController:myModalViewController animated:YES];

当模态视图控制器消失时,我希望“第 1 页”上的值根据用户在模态视图控制器中输入的内容进行更改。所以,我写了一些这样的代码,它驻留在模态视图控制器中:

[self.parentViewController dismissModalViewControllerAnimated:YES];
[self.parentViewController doSomethingPleaseWithSomeData:someData];

没有更新到第 1 页,我花了很长时间才意识到“doSomethingPleaseWithSomeData”消息没有发送到 Page1ViewController,而是导航控制器。

使用导航控制器时是否总是可以预料到这一点?我是否可能配置不正确?有没有一种简单的方法可以访问我想要的视图控制器(在本例中为 Page1ViewController)。

4

4 回答 4

14

我建议使用委托模式来解决您的问题。创建属性

@property (nonatomic, assign) id <MyModalViewDelegate> delegate;

以及相应的协议

@protocol MyModalViewDelegate
@optional
    - (void)myModalViewControllerDidFinish:(MyModalViewController *)aModalViewController;
@end

当用户完成您的视图(例如点击保存按钮)时,发送此消息:

if ([self.delegate respondsToSelector:@selector(myModalViewControllerDidFinish:)])
    [self.delegate myModalViewControllerDidFinish:self];

现在,将委托设置为应该管理整个事情的视图控制器,当视图控制器完成时它会收到通知。请注意,您需要您的视图控制器来关闭模态视图控制器。但是,从逻辑上讲,这是有道理的,因为它是首先呈现模态视图控制器的对象。

这就是 Apple 在 UIImagePickerController 和 UIPersonPickerController 中解决此问题的方法。

于 2008-11-11T15:51:18.490 回答
4

有几种方法可以处理这个问题。最简单的可能只是将 UIViewController 属性添加到 myModalViewController 并在呈现之前将其设置为 page1Controller:

myModalViewController.logicalParent = self; //page1Controller
[self presentModalViewController:myModalViewController animated:YES];

只需确保将适当的实例变量@property 和用于logicalParent 的@synthesize 添加到myModalViewController,然后您就可以将数据传回触发模态对话框的ViewController。这也用于在将数据推送到堆栈并将其弹出之前在不同导航级别之间来回传递数据。

这样做时要担心的一件重要事情是,如果您不小心,很容易获得保留循环。根据您的结构,您可能需要使用分配属性。

于 2008-10-28T20:08:22.053 回答
1

我刚刚遇到了同样的问题。显然,如果您将 UIViewController 嵌入到 NavigationController 中,那么当您从该 UIViewController 以模态方式呈现另一个 UIViewController 时,演示者认为演示者是 NavigationController。换句话说,parentViewController 是不正确的。

我敢打赌这是一个错误:要么,要么文档似乎不完整。我会查询的。

于 2010-09-24T15:39:32.107 回答
1

刚刚遇到了同样的问题。我相信这是一个错误。我的场景如下:按此顺序具有 A、B 和 C 视图控制器的导航层次结构。在 C 上,有一个按钮可以打开一个名为 D 的模式视图控制器。一旦呈现 D,导航控制器就会从其层次结构中删除 C,这是一种可怕的行为。一旦 D 被解除,导航控制器将实例化一个新的 C 类型视图控制器并将其推入其层次结构以恢复原始视图控制器。糟糕的。我的解决方案是以这种方式破解导航层次结构(一个非常糟糕的解决方案,但效果很好。使用二维数组,您可以实现堆叠模式):

- (void)presentModalViewController:(UIViewController *)c {
    [self.navigationHierarchy removeAllObjects];
    [self.navigationHierarchy addObjectsFromArray:[navigation viewControllers]];
    [navigation setViewControllers:[NSArray array] animated:YES];
    [navigation presentModalViewController:c animated:YES];
}

- (void)dismissModalViewController {
    [navigation dismissModalViewControllerAnimated:YES];
    [navigation setViewControllers:[NSArray arrayWithArray:self.navigationHierarchy] animated:YES];
}

这两种方法是在我维护主要导航层次结构的地方定义的:应用程序委托。导航和导航层次结构是这样定义的:

NSMutableArray *navigationHierarchy;
UINavigationController *navigation;
于 2010-12-18T13:21:25.470 回答