【问题标题】:Pass Information to Modal View Controllers将信息传递给模态视图控制器
【发布时间】:2014-07-21 12:56:25
【问题描述】:

我在这里阅读了一些关于从视图控制器传回数据的文章,我知道这肯定有一些禁忌,但我想询问以这种方式传递数据的最佳实践,并询问是否我在下面做什么可以吗?

我有 3 个视图控制器(ViewControllerA、B 和 C 类),当用户单击按钮(从 A 或 B)时,它会将它们带到 C 使用:

let vc = new ViewControllerC()
self.presentViewController(vc, animated: true, completion: nil)

向前传递数据 所以上面的'self'要么是A,要么是B。我的想法是,如果我想向C发送一些信息,我可以只创建C的一个属性(例如字符串或int等)并在之前分配它我做一个presentViewController。对吗?

即 vc.propertyHere = "我的价值"

传回数据 如果我想将 C 中发生的事情发回 A 或 B,那么最佳做法是什么? 要返回 A 或 B,我知道我可以这样做: self.dismissModalViewControllerAnimated(true)

我是否应该首先实例化 A 或 B(可能通过它们的基类型)并访问类似的属性以获取我想要传回的信息?例如,如果 A 和 B 都从某个类继承,我可以在该类上创建一个属性,然后从 C 访问/设置它。这是正确的举动吗?还是有更好的方法? 即

     callingViewController.myProperty = "my value i'm passing back"

谢谢!

【问题讨论】:

    标签: ios xcode ios7 swift ios8


    【解决方案1】:

    向前传递数据 - 你的实现很好。

    传回数据 -

    不要再次启动 A 和 B,这是我在新开发人员中看到的常见错误。 A 或 B 已经存在,您从 A/B 来到这个新控制器,您只想将一个值传递回该类。

    这里使用的最佳实践是委托设计模式。

    步骤:

    1. 创建一个协议,声明要在 A/B 中调用的 a 方法。

    2. 在 C 中实现一个名为 delegate 的属性。

    3. 在呈现视图 C 之前,分配委托。

    4. 只要您想将任何信息传递给 A 或 B,请调用委托方法。

    在此处的另一个 SO 答案中解释了实现委托:How do I create delegates in Objective-C?

    【讨论】:

      【解决方案2】:

      对于下坡,您在视图控制器上设置属性的建议在技术上没有问题

      vc.propertyHere = "my value"

      但是有一种称为Dependancy Injection 的模式可以在父母和孩子之间提供更清晰的对话。

      因此,如果您的新视图控制器需要某些功能,您可以在初始化时将其提供给实例。

      import Foundation
      import UIKit
      
      class ObjectTypeA {}
      class ObjectTypeB {}
      
      class FooVC : UIViewController {
      
      var importantThing:ObjectTypeA!
      var otherImportantThing:ObjectTypeB!
      
      init(somethingINeed:ObjectTypeA, somethingElseINeed:ObjectTypeB) {
      
          importantThing = somethingINeed
          otherImportantThing = somethingElseINeed
      
          super.init(nibName:nil,bundle:nil)
      
      }
      
      
      }
      
      class BarVC : UIViewController {
      
          func yo() {
      
              let object1 = ObjectTypeA()
              let object2 = ObjectTypeB()
      
              let newVC = FooVC(somethingINeed: object1, somethingElseINeed: object2)
      
              self.presentViewController(newVC, animated: true, completion: nil)
      
          }
      
      }
      

      所以继续做你正在做的事情,但在未来看看其他模式。

      对于向上传递数据或事件,最好使用其他人描述的委托模式。这样,父母和孩子之间就没有紧密的耦合。任何采用该协议的对象都可以成为委托。

      例如

      class BlueSuedeShoes{}
      
      protocol FunkyProtocol {
      
          func danceLikeElvis(shoes:BlueSuedeShoes)
      
      }
      
      class LumpyVC:UIViewController  {
      
          var delegate:FunkyProtocol?
      
          func somethingHappened() {
      
              let myShoes = BlueSuedeShoes()
      
              self.delegate?.danceLikeElvis(myShoes)
          }
      }
      

      以及实现该协议的类

      class SmoothVC:UIViewController,FunkyProtocol {
      
      
          func danceLikeElvis(shoes: BlueSuedeShoes) {
      
              dontStepOn(shoes)
      
          }
      
          func dontStepOn(shoes:BlueSuedeShoes) {
      
      
          }
      
      
      }
      

      【讨论】:

      • 所以 A 和 B 都将用户重定向到 C。我会定义一个协议(可能在 A 和 B 的基类中?),然后我会像上面那样在 C 中创建一个变量(委托: FunkyProtocol) 并且当我准备好传递我的值时,我只需像您在上面所做的那样调用它,并且可以在 A 中访问该信息。对吗?
      • 是的。在新文件或 A 或 B 中声明协议。在设置 C 时设置委托,记住委托不必是 A/B,它可以是采用该协议的任何东西。在 A/B 中实现协议方法,然后您可以通过这些委托方法传递您的信息。考虑一下 tableview 用来展示自己的所有委托/数据源方法。完全一样,你只是在创建自己的协议
      【解决方案3】:

      您可以使用委托模式来实现这一点。这是一个小例子,请看。

      @protocol SecondViewControllerDelegate;
      
      @interface SecondViewController;
      
      SecondViewController : UIViewController
      
      @property (nonatomic, assign) id<SecondViewControllerDelegate> delegate;
      @property (nonatomic, retain) NSArray* someArray;
      
      @end
      
      @protocol SecondViewControllerDelegate
      - (void)secondViewControllerDidFinish:(SecondViewController*)secondViewController;
      @end
      

      SecondViewController.m:

      @implementation SecondViewController
      
      @synthesize delegate;
      @synthesize someArray;
      
      - (void)dealloc
      {
          [someArray release];
          [super dealloc];
      }
      
      - (void)someMethodCalledWhenUserIsDone
      {
          [delegate secondViewControllerDidFinish:self];
      }
      

      FirstViewController.h:

      #import SecondViewController
      
      @interface FirstViewController : UIViewController <SecondViewControllerDelegate>
      {
          ...
      }
      
      @end
      

      FirstViewController.m:

      @implementation FirstViewController
      
      - (void)secondViewControllerDidFinish:(SecondViewController*)secondViewController
      {
          NSArray* someArray = secondViewController.someArray
          // Do something with the array
      }
      
      @end
      

      【讨论】:

      • OP 在 Swift 中执行此操作,而不是 ObjC。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-30
      • 1970-01-01
      相关资源
      最近更新 更多