如何从模态视图控制器中调用呈现视图控制器上的方法

5
我有一个模态视图控制器,我从另一个视图控制器中调用它。在模态视图控制器关闭时,我希望在呈现该模态视图的视图控制器上调用一个方法。最简单的方法是什么?
我尝试在我的模态视图控制器中执行以下操作:[(ParentViewController*)self.presentingViewController foo]; ,然后调用[self dismissViewControllerAnimated:YES completion:nil];
Xcode 给我一个错误,说foo没有被识别,即使它在控制器中定义和声明了。如果您的解决方案涉及块,则我真的不理解它们,因此如果您能添加更多细节,我将不胜感激。谢谢。
ParentViewController.h
@interface ParentViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource>
{
    NewAssignmentViewController *newAssignmentViewController;
    TableViewDataSource *data;
}

-(void)foo;

@end

2
你会得到那个错误是因为编译器不知道self.presentingViewController这个类是什么。要修复它,只需进行强制转换:[(MyClass *)self.presentingViewController foo] - rdelmar
请在ParentViewController.h中包含您的代码。 - rdelmar
我认为问题不在于foo的实现,因为即使foo什么也不做,程序仍会崩溃。 - Iowa15
1
在你关闭模态视图控制器之前,加入一个日志:NSLog(@"%@",[self.presentingViewController class]),看看它返回了什么。 - rdelmar
好的,那是你的问题。你从未提到这些控制器嵌入了一个选项卡栏控制器中。当你从选项卡栏控制器中的一个控制器进行演示时,实际上是选项卡栏控制器进行演示,而不是你调用它的控制器进行演示。 - rdelmar
显示剩余4条评论
3个回答

11

你需要这样正确地引用你的 presenting 控制器:

ParentViewController *presenter = [(UITabBarController *)self.presentingViewController viewControllers][0]; // 0 is assuming that ParentViewController is in the first tab. Change if necessary
[presenter foo];

另一种方法是使用委托,但这需要另外解释。


2
如果您使用故事板转场来呈现视图控制器,则可以使用回溯转场将其解除。回溯转场是一种特殊的转场方式,它将呈现的视图控制器返回到呈现者。
为了实现这一点,您需要在呈现视图控制器中创建一个方法,具有以下签名:
- (IBAction)unwindAction:(UIStoryboardSegue*)unwindSegue;

与标准的IBAction不同,这里的参数类型是UIStoryboardSegue*而不是普通的id类型(它的名称不一定是unwindSegue:,也可以是modalViewFinished:或其他你喜欢的名称,重要的是它具有返回类型IBAction和参数类型UIStoryboardSegue*)。

定义好这个方法后,在你的故事板中,从模态视图控制器图标(在其视图下方的小图标栏中)控制拖动并释放连接到绿色退出标志。这将创建一个反向连线,你应该在属性检查器中为其指定一个identifier。反向连线不会在故事板画布上显示出来,所以你需要在画布左侧的项目列表中找到它(默认情况下此列表是折叠的,可以通过单击画布左下角的小圆形按钮展开)。

完成上述步骤后,不要再调用[self dismissViewControllerAnimated:YES completion:nil],而是调用[self performSegue:<你给反向连线起的名称>]。在此过程中,呈现视图控制器上定义的unwindAction:方法和模态视图控制器上的prepareForSegue:方法应该会被调用。你可以在这些方法中进行任何必要的清理(例如,从unwindSegue:调用foo方法)。


谢谢,但我不使用故事板。 - Iowa15
@Iowa15 啊,太遗憾了,退出过渡很好用。 - Charles A.
是的,我刚开始学习iPhone编程,但下次我一定会用它们。 - Iowa15
@CharlesA。在调用modalViewFinished:之后,我收到了尝试从视图控制器<MyTabBarController: 0xc233600>中解除显示,而此时正在进行演示或解除显示!的错误提示。模态视图仍然停留在屏幕上。我该怎么办? - expert
@ruslan 听起来好像仍然有一些代码在某个地方明确地解除了你的视图控制器。你需要将其移除,unwind segue 会为你完成这个操作。 - Charles A.

0

您需要在主视图控制器上调用该方法,并将您想要作为操作表的视图控制器传递给它。

UIActionSheet *actionSheetController =[[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@"show otherview", nil];
 [self presentModalViewController:actionSheetController animated:YES ];

要关闭UIActionSheet,可以使用dimissWithClickedButtonIndex:animated:方法。该方法是UIActionSheet的一个实现。任何人都可以调用该方法(因此,如果您想从主视图中关闭它,请引用操作表并执行类似以下的操作)。
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
{
        switch (buttonIndex){
            case 0:
            {
               [actionSheet dismissWithClickedButtonIndex:0 animated:YES];
            }
                break;

            case 1:
            {
                MyClass *myclassObject = [[MyClass alloc]init]; 
                [myclassObject foo];
            }
       }
}

每当用户点击“取消”按钮时,该方法也被调用。

请使用此链接 ModalViewControllers 以便更好地理解...!


请告诉我是否出现任何问题。 - chandan
使用创建自己的 presentingViewController 类引用来使用它。 MyClass *myclassObject = [[MyClass alloc]init]; [myclassObject foo]; - chandan
我收到一个警告,指出:“从'UIViewController *'分配给MyClass *__strong'的不兼容指针类型”。 - Iowa15
使用强制类型转换会导致程序崩溃。 - Iowa15
在MyClass上将其称为foo没有问题。只有当我在呈现的视图控制器上调用它时才会崩溃。 - Iowa15
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接