我在从另一个控制器中动态更新一个控制器中的 UILabel 时遇到问题。它需要对应于在objective-c中选中的复选框

Posted

技术标签:

【中文标题】我在从另一个控制器中动态更新一个控制器中的 UILabel 时遇到问题。它需要对应于在objective-c中选中的复选框【英文标题】:I'm having trouble dynamically updating a UILabel in one controller from another. It needs to correspond to a checkbox being checked in objective-c 【发布时间】:2014-05-21 23:01:55 【问题描述】:

正在开发一个购物商店应用程序。在过去的一个半星期里,我一直在兜圈子,试图弄清楚如何正确地做到这一点。问题在于 UILabel 需要使用与选中复选框相对应的文本进行动态更新。它还需要知道是否在点击应用按钮时应用选择,或者如果客户决定改变主意而不点击应用,则返回先前的选择。这就是我遇到问题的地方。

我将 3 个控制器称为图像 1、图像 2 和图像 3。

我的模型是一个单独的类,我来回传递副本,以保留用户在希望优化服装项目结果集合时所做的选择。

例如,用户点击图片 1 中的优化按钮

他们被带到图像 2,在那里他们决定他们想要通过什么来优化结果

然后他们被带到图像 3 页面并在那里进行选择

问题从何而来:

简而言之,在图 3 中,客户进行选择并点击完成,然后将他们带回图 2,其中他们的选择显示在一个字符串中,在 UILabel 中以逗号分隔,位于所选细化选项下方,例如性别。如果他们对他们的选择满意,他们点击应用,精炼完成并显示,如图 1 所示。精炼按钮中还会显示一个勾号,以使客户知道精炼处于活动状态。

现在假设已经做出了如下图所示的选择,客户返回到图 3 以修改选择。假设他未选中“微型网站”。应该发生的是,当他返回图像 2 时,应该更新优化选项下方的列表。

这很好用,但我实际上是在更新点击应用按钮时更新的属性。因此,如果客户决定他们不想再进行优化并且不单击应用,而是单击后退按钮将它们带到图像 1,那么我需要在属性中更新原始选择字符串。

问题是,每当在图 3 中进行选择时,此属性就会更新。因此,当客户确实返回到图 2 时,因为我们未选中“微型网站”,所以只有“男性”将显示在优化选项下方的字符串中.

我已经尝试创建一个临时属性来保存之前的选择,但是这一切来来回回真的让事情变得一团糟。

更多信息:

我使用 prepareForSegue 方法和委托/协议在控制器之间来回传递我的模型类。

当点击图 3 中的完成按钮时,图 2 会知道。这是我传递模型的地方。图 1 知道何时点击了图 2 中的应用按钮,这也是我将模型传递过来的地方。要将模型从图像 1 传递到 2,然后从 2 传递到 3,我使用 prepareForSegue 方法。

图片 1:

图 2:

图 3:

你会怎么做?我觉得我已经有了一个良好的开端,将我所有的模型都移到了自己的类中。这让事情变得更容易了,但 UILabel 的另一个问题阻碍了我。

更新:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender


    if ([[[sender titleLabel] text] isEqualToString:@"Gender"]) 

        VAGRefineGenderViewController *vc = [segue destinationViewController];

        [vc setDelegate:self];

        [vc setRefineModel:[self refineModel]];
    

工作代码:

@implementation VAGRefineModel

    VAGRefineModel *_object;


-(id)copyWithZone:(NSZone *)zone


    VAGRefineModel *modelCopy = [[VAGRefineModel alloc] init];
    modelCopy->_object = [_object copyWithZone: zone];
    return modelCopy;

然后在图像 2/控制器 2 中,我只是将传递给控制器​​ 3 的模型设置为现有模型的副本。

【问题讨论】:

你使用什么机制让 vc2 知道在 vc3 中已经点击了 done?代表、区块或其他? @Paul.s 我使用代表。我将模型实例传递给一个名为 didTapDoneButtonWithModel: 的方法。然后在控制器 2 中调用该方法,然后将我的模型属性设置为该实例。 您需要做的就是传递适当的可寻址性。 非常感谢你在没有解释原因的情况下标记了我。竖起大拇指 【参考方案1】:

这看起来相当简单。

您确实应该创建模型的副本并将其传递给下一个 viewController,这样您就不必担心对其进行的编辑。 如果用户按回,则该副本将被丢弃。 如果您按完成,那么您会收到副本并替换您当前的模型,然后重新加载您的视图。

它可能看起来就这么简单(没有错误处理使其易于理解)

 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender;

  Model *model = [self.model copy];

  VC2 *viewController = segue.destinationViewController;
  viewController.model    = model;
  viewController.delegate = self;


- (void)didTapDoneButtonWithModel:(Model *)model;

  self.model = model;
  [self reloadData];

【讨论】:

刚刚将控制器 2 的 prepareForSegue 方法添加到问题中。所以基本上我需要将模型实例的副本传递给控制器​​ 3? 由于某种原因我开始 -[VAGRefineModel copyWithZone:]: unrecognized selector sent to instance 您将需要手动实现复制 - 请参阅其他帖子以获取提示。例如***.com/questions/1459598/… 完美运行。我在我的模型 .h 类中声明了 NSCopying 并且还在我的模型类 .m 文件中实现了 copyWithZone 方法。我以前从来没有使用过 -> 运算符,但在这种情况下我做到了。我已经把代码放在上面了。【参考方案2】:

我没有详细阅读您的帖子,但确实阅读了足够多的内容。

我将把你的屏幕称为 1 级(主)、2 级(***细节)和 3 级(精细细节)而不是图像 1/2/3,因为我在谈论图片,我是谈论主/细节视图控制器。

听起来您有 3 个级别的视图控制器,允许用户编辑更精细级别的搜索。

我建议设置您的模型,以便您可以将级别 2 和 3 处理的细节封装到对象中。当您准备好降到第 3 级时,创建性别和微网站设置的副本,并将其传递给级别视图控制器。用户将与级别 3 交互,该级别拥有自己的设置副本。

Level 3 应该设置 level 2 作为它的委托,带有委托消息

-userChangedSettings: (Level3SettingsObject *) changedSettings

或类似的东西。

如果点击完成,第 3 级 VC 将在其委托上调用该方法,将更改传递给 Level3Settings 对象直至第 2 级,然后自行弹出/自行关闭。 (以适当的为准。)

如果用户点击取消,只需关闭弹出/关闭而不调用委托方法来告诉委托有关设置的更改。 2 级对象中的设置不会改变。

第 2 级与第 1 级之间的通信也是如此。

如果有意义,您可以使级别 1 的设置包含级别 2 数据对象,而级别 2 的设置包含级别 3 数据对象。这样,对级别 3 的更改会传递回级别 2,如果用户从级别 2 取消,则在级别 2 和级别 3 中所做的所有更改都将被丢弃,并且只有当他们在级别 2 中点击保存时才会从该级别进行更改升到 1 级。

【讨论】:

我用最终对我有用的方法编辑了我的问题。我使用了 NSCopying。

以上是关于我在从另一个控制器中动态更新一个控制器中的 UILabel 时遇到问题。它需要对应于在objective-c中选中的复选框的主要内容,如果未能解决你的问题,请参考以下文章

从另一个视图控制器更新视图控制器的内容而不打开它

从另一个视图控制器更新 UIPageControl

从另一个类 Swift 更新视图控制器的 UI [关闭]

如何快速从另一个视图控制器重新加载表格视图

从另一个视图控制器中的类中快速绘制形状(以编程方式)

从另一个类和线程更新 UI 项