通过导航控制器调用父视图控制器

7

我现在使用pushViewController:animated:添加了一个视图控制器,现在想从这个新控制器内部调用我的“父”控制器中的方法。我认为我卡在了导航控制器上。

目前正在尝试这个来查看它是否是我想要的控制器:

if([self.superclass isKindOfClass:[MySuperController class]])
// and tried:
if([self.presentingViewController isKindOfClass:[MySuperController class]])

这两个都无效。

我该如何访问控制器(其中一个方法)并推送当前控制器的方法?


你应该在第二个视图控制器上声明一个委托,并在“ParentViewController”上实现它们。 - Marsson
@Marsson,那会是什么样子?<MySuperControllerDelegate>然后呢? - Pangolin
3个回答

37

就像Marsson提到的那样,您需要使用代理(delegate)...

以下是一个示例:

在您的子视图控制器(child view controller)的.h文件中:

@protocol ChildViewControllerDelegate <NSObject>
- (void)parentMethodThatChildCanCall;
@end

@interface ChildViewController : UIViewController 
{
}
@property (assign) id <ChildViewControllerDelegate> delegate;
在你的子视图控制器的 .m 文件中:
@implementation ChildViewController
@synthesize delegate;


// to call parent method:
//  [self.delegate parentMethodThatChildCanCall];

在父视图控制器的 .h 文件中:

@interface parentViewController <ChildViewControllerDelegate>

在父视图控制器 .m 文件中:

//after create instant of your ChildViewController
childViewController.delegate = self;

- (void) parentMethodThatChildCanCall
{
  //do thing
}

太好了!谢谢 :D - 我使用 [self.delegate myMethod]; 在子类中调用了该方法。 - Pangolin
我一整天都在苦苦挣扎,直到我找到了这个答案。我忘记将childviewcontroller的代理设置为self。感谢您的回答 :-)。 - Holger Sindbaek

4
self.navigationController.viewControllers

返回导航堆栈中所有视图控制器的数组。当前视图控制器位于堆栈顶部,上一个视图控制器在下面,以此类推。

所以,您可以执行以下操作:

NSArray *viewControllers =     self.navigationController.viewControllers;
int count = [viewControllers count];
id previousController = [viewControllers objectAtIndex:count - 2];
if ([previousController respondsToSelector:@selector(myMethod)])
    [previousController myMethod];

如果您知道前一个控制器的类,可以将其显式转换而不使用id。

看起来是一个合法的方式,但是当我用NSLog输出时,count0 - Pangolin
这意味着navigationcontroller为空,我假设你从问题中使用了一个导航控制器,这是错误的吗? - jrturton

1
不确定您的应用程序逻辑,但您总是可以这样做。 在您的“子”控制器中,声明类型为父控制器的属性。因此,在.h文件中:
MySuperController *superController;
property(nonatomic, retain)MysuperController *superController;

在你的 .m 文件中:

@synthesize superController;

在“推送”您的子控制器之前:
MyChildController *child = ...
[child setSuperController:self];
[self.navigationController pushViewController:child animated:YES];

然后在您的子控制器中,您可以简单地访问您的父级控制器:

[this.superController myMethod:param];

我不会倡导这种编码方式,但这是一种快速/廉价/粗略完成任务的方法。


好的,谢谢。当我尝试使用[child setSuperController:self];时,它警告我尝试发送MySuperController*而不是int *...奇怪? - Pangolin
啊,做不了这个。它会创建无限循环(它们相互导入)。 - Pangolin

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