【问题标题】:MVC consistency, present a viewController from the modelMVC 一致性,从模型中呈现一个 viewController
【发布时间】:2012-09-11 20:20:16
【问题描述】:

我有一个在情节提要中内置的 viewController。我还有一个 NSObject 子类,它充当我的模型,它发送和侦听 API 请求和响应。当一个方法在我的模型中触发时,我想从当时恰好可见的任何视图中呈现我的 viewController 的模态视图。

例如,如果我的 API 听到“显示此视图”,我想显示 viewController 而不管显示的是什么视图。

从概念上讲,如何做到这一点?

编辑:当我想展示我的模态视图控制器时,我不知道将显示哪个视图控制器。此外,当它出现时,我需要将模型中的参数传递给 modalVC。

【问题讨论】:

    标签: ios iphone uiviewcontroller modalviewcontroller


    【解决方案1】:

    我会从模型发送通知,告诉“某人”需要显示某些视图。

    NSDictionary *userInfo = @{ @"TheViewKey": viewToDisplay];
    [[NSNoticationCenter defaultCenter] postNotificationName:@"NotificationThatThisViewNeedsToBeDisplayed" object:self userInfo:userInfo];
    

    然后委托(或活动视图控制器)将注册到此通知并处理显示。

    // self is the delegate and/or the view controller that will receive the notification
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleViewToDisplay:) name:@"NotificationThatThisViewNeedsToBeDisplayed" object:nil];
    

    如果你放入视图控制器,记得在视图不可见时从观察者中移除 self:

    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"NotificationThatThisViewNeedsToBeDisplayed"];
    

    通过这种方式,您的模型与演示文稿分离。

    【讨论】:

      【解决方案2】:

      您有当前的 viewController(任何 viewController 子类)使用以下方式呈现新视图:

      - (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion
      

      编辑:要找到顶视图控制器,您向 UITabBarController 询问 selectedViewController(如果您使用 tabBarController)来获取“种子”,或者从 window.rootViewController 开始。

      一旦你通过了任何 tabBarControllers,那么你应该只有 UIViewController 子类和 UINavigationControllers。您可以使用这样的循环:

      - (UIViewController *)frontmostController:(UIViewController *)seed
      {
          UIViewController *ret;
          if([seed isKindOfClass:[UINavigationController class]]) {
              ret = [(UINavigationController *)seed topViewController];
          } else
          if([seed isKindOfClass:[UIViewController class]]) {
              ret = seed.presentedViewController;
          }
          return ret ? [self frontmostController:ret] : seed;
      }
      

      【讨论】:

      • 我如何知道当前哪个 ViewController 可以调用 presentViewController?
      • 我看到您授予通知解决方案的答案 - 只要顶视图控制器是您的对象之一,它就会起作用。即使顶部对象是诸如电子邮件消息类之类的苹果类,上述解决方案也将起作用。另外,请注意,当说呈现的视图控制器辞职时,逻辑会变得有些棘手 - 每个视图控制器都必须具有正确的逻辑才能知道要注册回通知。确实,该解决方案与使用全局 UIViewController 并让您的各种类在它们成为最前面时将其设置为“self”没有什么不同。
      • 你能解释一下最后一行:return ret 吗? [self frontmostController:ret] : 种子;我不明白那是什么语言。
      • 我认为通知不会使这个 frontmostController: 方法无效。通知只是告诉何时调用该方法并处理新视图的显示。另外,我同意大卫的观点,你不应该把通知放在你所有的控制器中,明智地选择哪一个负责。对我来说,最重要的是将模型与视图逻辑分开。
      • 问题始终是在每个班级中确保班级在其成为最前沿时能够识别 - 这并不总是显而易见或直接的[问我是怎么知道的 :-)]
      猜你喜欢
      • 2020-10-16
      • 1970-01-01
      • 2012-02-13
      • 2017-07-03
      • 2018-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多