【问题标题】:Calling Method From Another UIViewController Has No Visible Effect从另一个 UIViewController 调用方法没有可见效果
【发布时间】:2014-08-10 08:04:48
【问题描述】:

我有两个类,想在按下按钮时从一个类调用一个方法。我在我的 .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 值。

【问题讨论】:

  • 您正在创建一个新的SecondViewController 并更改其图像。那是没有意义的。您需要引用现有的 SecondViewController 并更改其图像。
  • @rmaddy 我应该更改什么代码?
  • @user3750491,与其说是改变不如说是增加:SecondViewController 是否呈现了这个视图控制器?
  • @danh 你能解释一下吗?我是 Objective-C 的新手。谢谢!
  • 使用delegation!

标签: ios objective-c cocoa-touch uiviewcontroller


【解决方案1】:

这个问题是一个常见问题的变体:“如何在视图控制器之间传递值”,您的代码代表了解决方案的常见尝试。让我们从你所做的开始。

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

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 的首选模式。有很多关于如何做到这一点的网络和 SO 资源,所以我不会在这里重复。 Check out this, for example,或谷歌“iOS 委托”。

还有其他方式,例如 NSNotificationCenter 向所有感兴趣的人广播您想要交流的任何内容,或者让 SecondVC 观察模型中的变化并做出反应的 KVO,无论这种变化是如何或为什么发生的。

后两者的关键概念是您的应用需要有一个模型,即一组描述应用状态的对象。视图控制器不是模型——事实上它们完全不是模型。他们的工作是了解模型更改并相应地修改视图。

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

希望这已经足够清楚了。祝你好运。

【讨论】:

  • 惊人的解释!感谢一切!你摇滚!
  • 非常感谢您让我过得愉快!今天是我的 14 岁生日,感谢这份特殊的礼物,它帮助我修复了困扰我很久的错误!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多