我对iOS和Objective-C以及整个MVC范式都是新手,我一直坚持以下几点:

我有一个充当数据输入表单的视图,我想让用户选择多个产品。产品列在另一个具有UITableViewController的视图中,我已启用多个选项。

如何将数据从一个视图传输到另一个视图?我会将UITableView上的选择保存在一个数组中,但如何将其传递回上一个数据输入表单视图,以便在提交表单时将其与其他数据一起保存到核心数据?

我在网上冲浪,看到一些人在应用程序委托中声明了一个数组。我读了一些关于单态的东西,但我不明白这些是什么,我读了关于创建数据模型的东西。

正确的执行方式是什么?我将如何执行?


当前回答

您可以将数据保存在App代理中,以便通过应用程序中的视图控制器访问数据。您只需创建应用程序委托的共享实例:

AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;

例如

如果声明NSArray对象*arrayXYZ,则可以通过appDelegate.arrayXYZ在任何视图控制器中访问它。

其他回答

这是一个非常古老的答案,这是反模式的。请使用委托。不要使用这种方法!!

1.在第二个视图控制器中创建第一个视图控制器的实例,并使其属性@property(nonatomic,assign)。

2.分配此视图控制器的SecondviewController实例。

2.完成选择操作后,将阵列复制到第一个视图控制器。卸载第二个视图时,第一个视图将保存阵列数据。

我建议使用块/闭包和自定义构造函数。

假设您必须将字符串从FirstViewController传递到SecondViewController。

您的第一个视图控制器。

class FirstViewController : UIViewController {

    func moveToViewControllerB() {

        let second_screen = SecondViewController.screen(string: "DATA TO PASS", call_back: {
            [weak self] (updated_data) in
            ///This closure will be called by second view controller when it updates something
        })
        self.navigationController?.pushViewController(second_screen, animated: true)
    }


}

第二个视图控制器

class SecondViewController : UIViewController {

    var incoming_string : String?
    var call_back : ((String) -> Void)?

    class func screen(string: String?, call_back : ((String) -> Void)?) -> SecondViewController {

        let me = SecondViewController(nibName: String(describing: self), bundle: Bundle.main);
        me.incoming_string = string
        me.call_back = call_back
        return me
    }

    // Suppose its called when you have to update FirstViewController with new data.
    func updatedSomething() {

        //Executing block that is implemented/assigned by the FirstViewController.
        self.call_back?("UPDATED DATA")
    }

}

经过更多的研究,协议和代表似乎是正确的/苹果首选的方式。

我最终使用了这个示例(在iPhone开发SDK中):

在视图控制器和其他对象之间共享数据

它工作得很好,允许我在视图之间前后传递字符串和数组。

我喜欢基于NSProxy的模型对象和模拟对象的想法,以便在用户选择的内容可以取消时提交或丢弃数据。

传递数据很容易,因为它是一个对象或两个对象,如果你有一个UINavigationController控制器,你可以将对模型的引用保存在内部,所有推送视图控制器都可以直接从导航控制器访问它。

我更喜欢在没有代表和片段的情况下进行。它可以通过自定义init或设置可选值来完成。

1.自定义初始化

class ViewControllerA: UIViewController {
  func openViewControllerB() {
    let viewController = ViewControllerB(string: "Blabla", completionClosure: { success in
      print(success)
    })
    navigationController?.pushViewController(animated: true)
  }
}

class ViewControllerB: UIViewController {
  private let completionClosure: ((Bool) -> Void)
  init(string: String, completionClosure: ((Bool) -> Void)) {
    self.completionClosure = completionClosure
    super.init(nibName: nil, bundle: nil)
    title = string
  }

  func finishWork() {
    completionClosure()
  }
}

2.可选变量

class ViewControllerA: UIViewController {
  func openViewControllerB() {
    let viewController = ViewControllerB()
    viewController.string = "Blabla"
    viewController.completionClosure = { success in
      print(success)
    }
    navigationController?.pushViewController(animated: true)
  }
}

class ViewControllerB: UIViewController {
  var string: String? {
    didSet {
      title = string
    }
  }
  var completionClosure: ((Bool) -> Void)?

  func finishWork() {
    completionClosure?()
  }
}