来自另一个UIViewController的调用方法没有可见效果

C-O*_*D-E 5 cocoa-touch objective-c uiviewcontroller ios

我有两个类,并且想要在按下按钮时从一个类调用一个方法.我在我的.h文件中声明它如此:

-(void) imageChange;
Run Code Online (Sandbox Code Playgroud)

我在我的.m中创建了这样的方法:

-(void)imageChange {
    UIImage *image = [UIImage imageNamed: img];
    [_MyImage setImage:image];
}
Run Code Online (Sandbox Code Playgroud)

最后,我尝试使用以下方法从另一个类调用该方法:

- (IBAction)Done:(id)sender {

    SecondViewController *theInstance = [[SecondViewController alloc] init];
    [theInstance imageChange];
    [self dismissViewControllerAnimated:YES completion:nil];

}
Run Code Online (Sandbox Code Playgroud)

但是,当我在视图控制器中按"完成"时,UIImage不会改变.请注意:img是一个NSString值.

dan*_*anh 8

问题是常见的变体:"如何在视图控制器之间传递值",而您的代码代表了解决方案的常见尝试.让我们从你做的开始吧.

您的应用程序有两个视图控制器,视图堆栈上有视图,您希望在它们之间进行通信.这一行:

SecondViewController *theInstance = [[SecondViewController alloc] init];
Run Code Online (Sandbox Code Playgroud)

创建一个全新的SecondViewController实例(alloc意味着为这个类的新实例分配内存).这一行:

[theInstance imageChange];
Run Code Online (Sandbox Code Playgroud)

与它进行通信,在您的情况下,它看起来像设置图像视图的图像.那么这一行:

}
Run Code Online (Sandbox Code Playgroud)

隐含地破坏了那个新实例,因为它再也没有被引用过.因此,您的代码成功地与SecondViewController进行通信,但是使用了错误的实例,这个实例只能存活几毫秒.

好的,怎么办呢?@rmaddy说的是找到SecondViewController的现有实例,并与之通信.如何获得现有实例取决于我们如何到达这里.你的代码中的dismissViewControllerAnimated让我觉得这个当前的vc是由SecondVC的一个实例呈现的.如果是这样,

(SecondViewController *)self.presentingViewController
Run Code Online (Sandbox Code Playgroud)

指出你需要什么.如果我们在一个UINavigationController,你可以挖掘它的viewControllers堆栈,可能在这里:

NSArray *stack = self.navigationController.viewControllers;
SecondViewController *secondVC = stack[stack.count-2];
Run Code Online (Sandbox Code Playgroud)

但是,虽然所有这些可能是从A到B的最直线,但它不是很好的设计,因为它使得当前的视图控制器以一种脆弱的方式依赖于它如何呈现.

因此@CrimsonChris提出了考虑授权的好建议.对于需要与另一个人进行通信的vc来说,这是大多数人的首选模式.有关如何执行此操作的大量Web和SO资源,因此我在此不再重复. 例如,看看这个,或谷歌"iOS代表团".

还有其他方法,比如NSNotificationCenter向所有想要传达的人感兴趣,或KVO让SecondVC观察模型的变化并做出反应,无论变化的方式和原因如何.

后两者的关键概念是您的应用程序需要一个模型,一组描述应用程序状态的对象.视图控制器不是模型-事实上他们究竟不是模型.他们的工作是了解模型更改并相应地修改视图.

对于您的情况,您发布的代码不应该尝试在另一个视图控制器中获取图像集,它应该在模型中记录触发解雇的任何用户操作.当这个当前的vc解散自己时,SecondViewController(假设它完成了当前)将得到一个viewWillAppear.该方法可能是检查在用户操作上设置的模型条件的好地方.然后SecondViewController可以自己调用imageChange.

希望足够清楚.祝好运.

  • 非常感谢你刚刚结束了我的一天!这是我的14岁生日,感谢这份特别的礼物帮助我解决了困扰我这么长时间的错误! (2认同)