我有两个类,想要在按下按钮时从一个类调用一个方法。我在我的.h文件中声明它如此:
-(void) imageChange;
我在我的.m中创建了这个方法:
-(void)imageChange {
UIImage *image = [UIImage imageNamed: img];
[_MyImage setImage:image];
}
最后,我尝试使用以下方法从另一个类调用该方法:
- (IBAction)Done:(id)sender {
SecondViewController *theInstance = [[SecondViewController alloc] init];
[theInstance imageChange];
[self dismissViewControllerAnimated:YES completion:nil];
}
然而,当我按下"完成"在我的视图控制器中,UIImage
没有变化。请注意:img
是NSString
值。
答案 0 :(得分:8)
问题是常见问题的变体:“如何在视图控制器之间传递值”,而您的代码代表了解决方案的常见尝试。让我们从你的所作所为开始。
您的应用有两个视图控制器,视图堆栈上有视图,您希望在它们之间进行通信。这一行:
SecondViewController *theInstance = [[SecondViewController alloc] init];
创建一个全新的 SecondViewController实例(alloc意味着为此类的新实例分配内存)。这一行:
[theInstance imageChange];
向它传达信息,在您的情况下,它看起来像设置图像视图的图像。然后这一行:
}
隐式销毁那个新实例,因为它再也没有被引用过。所以你的代码成功地与SecondViewController进行通信,但是使用了错误的实例,这个实例只能存活几毫秒。
好的,该怎么办? @rmaddy说的是找到SecondViewController的现有实例,并与之通信。如何获得现有实例取决于我们如何到达这里。你的代码中的dismissViewControllerAnimated让我觉得这个当前的vc是由SecondVC的一个实例呈现的。如果是的话,
(SecondViewController *)self.presentingViewController
指出你需要什么。如果我们在UINavigationController
,你可以挖掘它的viewControllers
堆栈,可能在这里:
NSArray *stack = self.navigationController.viewControllers;
SecondViewController *secondVC = stack[stack.count-2];
但是,虽然所有这些可能是从A到B的最直线,但它并不是很好的设计,因为它使得当前的视图控制器以一种脆弱的方式依赖它如何呈现。
因此@CrimsonChris提出了一个考虑授权的好建议。对于需要与另一个人进行通信的vc来说,这是大多数人的首选模式。有关如何执行此操作的大量Web和SO资源,因此我在此不再重复。 Check out this, for example,或谷歌“iOS代表团”。
还有其他方式,例如NSNotificationCenter
向所有想要传达的人感兴趣,或KVO让SecondVC观察模型的变化并做出反应,无论变化的方式或原因如何制成。
后两者的关键概念是您的应用需要一个模型,一组描述应用状态的对象。视图控制器不是模型 - 实际上它们完全而不是模型。他们的工作是学习模型更改并相应地修改视图。
对于您的情况,您发布的代码不应该尝试在另一个视图控制器中设置图像,它应该记录到模型中的任何触发解雇的用户操作。当这个当前的vc解散自己时,SecondViewController(假设它完成了当前)将得到一个viewWillAppear。该方法可能是检查在用户操作上设置的模型条件的好地方。然后SecondViewController可以自己调用imageChange。
希望足够清楚。祝你好运。