【问题标题】:How to call method on presenting view controller from modal view controller如何从模态视图控制器调用呈现视图控制器的方法
【发布时间】:2013-08-12 04:48:27
【问题描述】:

我有一个从另一个视图控制器调用的模态视图控制器。在关闭模态视图控制器后,我希望在呈现该模态视图的视图控制器上调用一个方法。最简单的方法是什么?

我尝试在我的模态视图控制器中执行此操作:[(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

【问题讨论】:

  • 您会收到该错误,因为编译器不知道 self.presentingViewController 是什么类。要修复它,只需转换它: [(MyClass *)self.presentingViewController foo]
  • 请包含您在 ParentViewController.h 中的代码
  • 我认为问题不在于 foo 的实现,因为即使 foo 没有做任何事情,程序也会崩溃
  • 在关闭模态视图控制器 NSLog(@"%@",[self.presentingViewController class]) 之前登录并查看它返回的内容
  • UITabBarController...

标签: ios objective-c-blocks modalviewcontroller presentmodalviewcontroller


【解决方案1】:

您需要像这样正确引用您的演示控制器:

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

另一种方法是使用委托,但这是另一个答案。

【讨论】:

    【解决方案2】:

    如果您使用 Storyboard segue 来展示您的视图控制器,您可以使用 Unwind Segue 将其关闭。 unwind segue 是一种特殊的 segue,它将呈现的视图控制器展开回演示者。

    为此,您将在呈现视图控制器中创建一个具有以下签名的方法:

    - (IBAction)unwindAction:(UIStoryboardSegue*)unwindSegue;
    

    这与标准的IBAction 不同,因为参数类型是UIStoryboardSegue* 而不是普通的id 类型(不必命名为unwindSegue:,它可以是modalViewFinished: 或其他你喜欢 - 重要的是它的返回类型为IBAction,参数类型为UIStoryboardSegue*)。

    一旦你定义了这个方法,在你的故事板中,你控制并从模态视图控制器图标(在它的视图下方,在图标的小栏中)拖动并释放绿色退出标志上的连接。这将创建一个展开转场,您应该在属性检查器中给它一个identifier。展开转场不会在故事板画布中直观显示,因此您必须在画布左侧的项目列表中找到它(默认情况下这是折叠的,通过单击左下角的小圆形按钮将其展开画布的手角)。

    完成此操作后,无需调用[self dismissViewControllerAnimated:YES completion:nil],只需调用[self performSegue:&lt;Identifier you gave the unwind segue&gt;]。在此过程中,应调用呈现视图控制器上定义的unwindAction: 方法和模态视图控制器上的prepareForSegue: 方法。你可以在这些方法中做任何你需要做的清理工作(例如,从unwindSegue: 调用foo 方法)。

    【讨论】:

    • 谢谢,但我没有使用 Storyboards
    • @Iowa15 啊,太糟糕了,exit segues 很好。
    • 是的,我刚开始学习 iPhone 编程,但我下次一定会使用它们
    • @CharlesA。在调用modalViewFinished: 后,我得到Attempt to dismiss from view controller &lt;MyTabBarController: 0xc233600&gt; while a presentation or dismiss is in progress!。模态视图停留在屏幕上。我能做什么?
    • @ruslan 听起来有点像仍然有代码在某处显式地解除您的视图控制器。您需要删除它,展开转场会为您完成。
    【解决方案3】:

    您调用作为 MainView 的 UIViewController 上的方法,并将您希望成为 ActionSheet 的 UIViewController 传递给它。

    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 链接以更好地理解...!

    【讨论】:

    • 如果出现任何问题请告诉我。
    • 对此我还不是很清楚。我想要做的是让我的模态视图控制器在呈现它的视图控制器上调用一个方法
    • 通过创建 self.presentingViewController 类 MyClass *myclassObject = [[MyClass alloc]init]; 的引用来使用它[myclassObject foo];
    • 好的,我明白了。让我试试
    • 我收到一条警告:不兼容的指针类型分配给 MyClass __strong' from 'UIViewController'
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-20
    相关资源
    最近更新 更多