【问题标题】:Changing label's text in another view controller在另一个视图控制器中更改标签的文本
【发布时间】:2013-08-14 04:14:30
【问题描述】:

我有一个名为 FirstViewController 的视图控制器,还有一个名为 SecondViewController 的视图控制器。我用

展示第二个视图控制器
 UIViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"mainController"];
[self presentViewController:controller animated:YES completion:nil];

在 SecondViewController 的 .m 中,我想在 FirstViewController 中更改 UILabel 的文本。但是,标签的文本没有更新。当在 SecondViewController 中按下 UIButton 时,如何更新 FirstViewController 的标签?

【问题讨论】:

标签: objective-c uiviewcontroller uilabel


【解决方案1】:

你可以使用委托模式

首先创建您的委托协议

@class SecondViewController;

@protocol SecondViewControllerDelegate

-(void) updateLabelWithString:(NSString*)string

@end

@property (weak, nonatomic) id<SecondViewControllerDelegate>delegate;

在您的IBAction 中连接到您的UIButton

[self.delegate updateLabelWithString:yourString];

在 FirstViewController.h 中

#import "SecondViewController.h"

@interface FirstViewController : UIViewController <SecondViewControllerDelegate>

在 FirstViewController.m 中

-(void) updateLabelWithString:(NSString*)string {
   label.text = string;
} 

然后在创建控制器实例时,将 FirstViewController 设置为 mainViewController 的委托

controller.delegate = self;

【讨论】:

  • 赞成这个答案,以便 OP 可以了解有关委托模式的更多信息。作为一个新开发者,对我来说最难理解的事情之一就是委托模式。我不认为这是“最好的”解决方案,但值得学习。它使属性和引用在以后变得更有意义。
  • 我同意贾斯汀的一切。很好学,但不是用于在视图控制器之间传递值的模式。委托的一个很好的例子是将数据加载到 tableview 中。委派是当您希望在您的 veiw 控制器之外发生某些事情并且您当前的活动视图控制器在完成或激活时更新(屏幕上的活动触摸)。这与将值从一个视图控制器传递到另一个不同。
  • @JustinAmberson 和 BenCoffman,感谢您的意见,出于某种原因,在传递值时,委托始终是我的第一直觉,尤其是因为这是我学到的第一件事。希望 OP 将花时间考虑此线程中建议的所有选项
【解决方案2】:

这里还有其他很好的答案。我把这个贴出来,所以我可以确定你会看到它。我在这里给 cmets 留下了您可能看不到的其他答案。

有几种方法可以实现您的解决方案。

  1. KVO(键值观察)

    KVO 是一种“观察”任何对象状态并在该对象发生变化时得到通知的方法。作为新开发人员,KVO 可能很难学习。像这样想。如果您知道 x = 1,并且想知道 x 是否发生变化,则可以设置为“观察”x。如果 x 发生更改,则会发生一个事件,并且您的“观察类”将被通知发生了更改,以及更改的范围是什么。我有时会监视可变数组的计数,以查看是否已添加或删除项目。

  2. NSNotification

    NSNotification 类似于 KVO,除了它没有什么自动的。与 KVO 一样,您设置了一个“观察者”类,并监听特定的“事件”发生。您选择事件发生的时间,然后创建一个 NSNotification 并“发布”它。任何作为“观察者”监听的类都会看到该通知并在适当的时候采取行动。

  3. 委托模式

    这是上面的答案。了解委派的工作原理很重要。对于您的确切情况,我认为这不是正确的做法,但它会起作用。由于“封装”,您需要委托,这意味着 A 类 不应 知道 B 类中发生了什么,反之亦然。使用委托可以鼓励类之间的独立性。

  4. 单例/共享实例

    我相信这是处理您当前问题的最佳方式。但是,这不是全部/全部。单例有助于实施“MVC”(模型、视图、控制器)模式编程。这是封装的一部分。 “模型”存储信息。 “视图”显示信息。 “控制器”将模型连接到视图。在这种情况下,您的第一个和第二个视图都是 MVC 的“V”约定的一部分。 “M”将是您的单例类。 “C”将是您的视图控制器,访问单例并显示值。

很抱歉没有详细说明如何做每一个。这四个本身就是教程。只是希望你带着新的理解前进。

编辑:我想指出我使用单例就像一个可移植的数据库。通常使用辅助方法设置,例如快速找到 libraryPath,编码为 NSData,以免弄乱 appDelegate。通常会有一个主数组对象存储多个类所需的信息。也许该数组有一堆 NSDictionaries 代表在线店面中的项目。我并不是要他开始在其中存储dataModel.classALabelText = @"Hello World";,但这是一个很好的起点

【讨论】:

  • 一个易失的便携式数据库。当应用程序关闭时它会消失。
  • 对,这就是我在其中实现归档方法的原因 :-)
  • 我认为你在正确的轨道上。我曾经在没有完全理解的情况下随意使用代表来处理各种事情
  • 感谢您花时间写出如此详细的答案。我想我会使用委托,因为它似乎是最容易理解的。再次感谢您的回答,我一定会研究其他方法以备将来使用
  • 我正在考虑写一篇关于这些内容的实事求是的博客文章,如果我愿意,我会告诉你
【解决方案3】:

如果您遵循模型-视图-控制器范式(或架构),那么您应该更改模型中的值(即,在实现您的模型的对象中)。然后,控制器层应确保所有相关视图都在 UI 中更新。

这样您就不必让视图控制器在它们之间传播更新。

【讨论】:

    【解决方案4】:

    执行此操作的最常见方法之一是创建一个 sharedInstance 类,无论您在哪个控制器中,您都可以在其中存储值,然后在显示您想要的控制器时从中读取.

    一个很好的例子:

    Question regarding SharedInstance

    这里有一个不错的教程:

    http://iphonedevsdk.com/forum/iphone-sdk-tutorials/24135-singleton-classes.html

    你也可以使用

    prepareForSegue:sender:
    

    Stackoverflow 上有很多这样的例子。

    【讨论】:

    • 有比单例更好的模式。例如:委托、通知、KVO...
    • 这些都是其他选项。不一定更好。我指的是我所看到的最常见的做法。我认为 KVO 无疑不是更好,但这又是一场辩论。对此投反对票并不酷。另外,为什么要使用委托并将两个类紧密耦合,那会很糟糕。我非常不同意你的说法。
    • 我支持你回到 0。我一直使用单例类,并且会同意你的回答。也许反对票是因为您的回答只是一些链接。也许您可以说明您在一个类中更新单例,而另一个类使用 NSNotification、KVO 或使用 UIViewController 的 viewWill... 方法监视内部的变化
    • 我投了反对票,因为大多数时候使用单例模式是错误的方法——并且谈论紧耦合!您不仅有一个正在写入的接口,而且只有一个实例!
    • 让我解释一下紧耦合。使用委托,您必须在要分配委托的类中声明委托方法。使用 SharedInstance,如果我不更新和/或检索数据,我无需更新任何内容、没有警告、没有错误,因此,它不是紧密耦合的。这可能有助于调整我们的想法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-25
    • 2016-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多