Iphone 调用父UIViewController函数
好吧,我有个问题,一直没能找到我做错了什么 我有一个UIVievController,它有一个视图和一些函数和东西。一个是打开(从操作表中的按钮)另一个Iphone 调用父UIViewController函数,iphone,cocoa-touch,uiviewcontroller,uikit,Iphone,Cocoa Touch,Uiviewcontroller,Uikit,好吧,我有个问题,一直没能找到我做错了什么 我有一个UIVievController,它有一个视图和一些函数和东西。一个是打开(从操作表中的按钮)另一个UIVeiwController。看起来像这样: PersonalSettings *personalSettings; -(IBAction) displaySettingsMenu:(id)sender { personalSettings = [[PersonalSettings alloc]
UIVeiwController
。看起来像这样:
PersonalSettings *personalSettings;
-(IBAction) displaySettingsMenu:(id)sender
{
personalSettings = [[PersonalSettings alloc]
initWithNibName:@"PersonalSettings"
bundle:nil];
[self.view addSubview:personalSettings.view];
[SettingsSheet dismissWithClickedButtonIndex:0 animated:YES];
}
[self.view removeFromSuperview];
MainViewController *Parent = (MainViewController *)self.superclass;
[Parent updateView];
这就像一个魅力,我可以在这个视图中进行som更新。
当我关闭此视图时,所有设置都会正确更新,视图也会消失,但我要做的是重新加载父视图ViewController
(视图?),以便查看我所做的新设置。我在父级中有一个void函数,但是我如何调用它呢?
当点击子视图控制器中的保存按钮时,我使用以下命令删除视图:
[self.view removeFromSuperview];
我要做的是从父视图的子视图调用update函数
我找到了一些这方面的代码,但例外是“超类”而不是“superview”,因为superview不出现在列表中。看起来像这样:
PersonalSettings *personalSettings;
-(IBAction) displaySettingsMenu:(id)sender
{
personalSettings = [[PersonalSettings alloc]
initWithNibName:@"PersonalSettings"
bundle:nil];
[self.view addSubview:personalSettings.view];
[SettingsSheet dismissWithClickedButtonIndex:0 animated:YES];
}
[self.view removeFromSuperview];
MainViewController *Parent = (MainViewController *)self.superclass;
[Parent updateView];
有什么“魔法”可以让我说“重新加载父视图”之类的话吗
我希望我已经让这个问题变得可以理解。:)
编辑:
真的谢谢你,gyus,我现在更近了。
我还不能100%确定这个委托是如何工作的,但我已经接近一个解决方案了。实际上,我意识到甚至不需要运行一个方法,只需更新一个标签
我从孩子那里写下了这样的话:
MainViewController* Parent = [[MainViewController alloc] init];
Parent.delegate = self;
Parent.TheLabel.text = @"foo";
…但这不起作用-即使它真的找到了标签和所有东西。如果我从孩子那里尝试这个:
NSLog(@"Parent label: %@", Parent.TheLabel.text);
它记录“父标签:(空)”
但是,我现在可以从子级访问update函数,它会运行。问题是该函数从其他标签(在父视图中)获取值,这就是它崩溃的地方——当我从子视图运行该函数时,它们都会说null。即使他们没有。想知道为什么吗?如果您熟悉代理模型,那么让您的家长查看代理并通过这种方式从孩子那里传回信息。你会在苹果网站上找到一些关于它的好文档 基本上,您将“委托”字段添加到孩子的“构造函数”中,即:
child = [[ViewController alloc] initWithDelegate:this withNibName:@"myNib"];
然后,在子类中,当您收到信息时,可以访问委托中的字段/方法
- (void) volumeDidChange:(int)volume
{
delegate.volume = volume
}
或者类似的。祝你好运 如果您正在寻找访问给定控制器的父级的通用方法,请查看以下方法:
+ (YOURTABBARCONTROLLER*)parentTabBarController:(UIResponder*)view {
id nextResponder = nil;
id v = view;
while (nextResponder = [v nextResponder]) {
if ([nextResponder isKindOfClass:[YOURTABBARCONTROLLER class]])
return nextResponder;
v = nextResponder;
}
return nil;
}
它将导航响应程序链,以返回在那里找到的给定类型的第一个类。您可以将TabbarController
设置为UIViewController
,或者指定具体的控制器类以获得更多控制。那么,你会说,例如:
YOURTABBARCONTROLLER* parent = [self parentTabController:self.view];
(如果self是您的子控制器,并且您在其中定义了上述方法)
这是你能找到的最接近的东西,阿福。该方法也可以被制作成UIViewController的一个类别,因此您总是可以在那里找到它
编辑:
如果您使用+
,那么像这样调用方法:[CLASSNAME parentTabController:view],其中CLASSNAME是您定义它的类。无论如何,您可以在方法声明中使用-
,它将与self
一起工作,如前所述
如果它不适合您,请发布您定义的完整方法,以及您调用它的确切方式。您还可以添加以下行:
NSLog(@"Found Responder: %@", nextResponder); //-- ADDED THIS
作为
while
循环的第一行,因此该方法将记录在响应者链中找到的内容。我同意aeoliant,使用委托模型可能更合适。这里有一个简单的解释因为我只是一个新手,并且将子视图添加为“addSubview”,所以我遇到了这些问题。使用-(void)presentModalViewController:(UIViewController*)modalViewController animated:(BOOL)animated更改视图成功!
无论如何,特别感谢kubi:)我希望我理解了你的问题:这与你的问题无关,但是当你想显示一个新视图和相关的
UIViewController
时,你应该使用视图控制器方法<代码>-(void)presentModalViewController:(UIViewController*)modalViewController动画:(BOOL)动画例如。如果您只是将控制器视图添加为子视图,那么您将失去使用视图控制器免费获得的所有漂亮的内存管理方法。很遗憾,我无法将您的评论标记为修复,这就成功了!现在,由于运行了视图加载,父级已正确更新。谢谢,感觉我在这里走对了方向。我对这个有点陌生,“+”是做什么的?当我使用此方法时,我在[self-parentTabBarController..]中找不到“parentTabBarController”,但我可以用“-”找到它。它没有给我任何错误或其他东西,但它也没有运行函数(我这样称呼它:[parent updateView];)好吧,我已经让它工作了——几乎。在更新的顶部,我有一个运行的nslog,但它不更新,也没有错误。更新将从数据库获取帖子,并将其显示在父视图中。所以它运行它,但不更新。当我在父视图中执行其他操作时,我只调用这个更新函数(实际上它是一个iAction而不是一个void),它工作得很好。但是,当我通过delegate方法从child调用它时,它似乎只是在运行,但没有做任何事情。有什么建议吗?在父类中,将父类本身设置为子类的委托,如child.delegate=self;。在子对象中,使用类似“updateParentLable:(nsstring*)text”的方法创建委托。要更新父级,请在子级调用[delegate UpdatePartnerLabel:text];在父级中,必须具有委托方法“updateParentLAbel:(nsstring*)text”,因此在该方法中,可以更新它自己的标签,如self.label=text。