我对iOS和Objective-C以及整个MVC范式都是新手,我一直坚持以下几点:
我有一个充当数据输入表单的视图,我想让用户选择多个产品。产品列在另一个具有UITableViewController的视图中,我已启用多个选项。
如何将数据从一个视图传输到另一个视图?我会将UITableView上的选择保存在一个数组中,但如何将其传递回上一个数据输入表单视图,以便在提交表单时将其与其他数据一起保存到核心数据?
我在网上冲浪,看到一些人在应用程序委托中声明了一个数组。我读了一些关于单态的东西,但我不明白这些是什么,我读了关于创建数据模型的东西。
正确的执行方式是什么?我将如何执行?
我建议使用块/闭包和自定义构造函数。
假设您必须将字符串从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")
}
}
使用通知中心
对于Swift 3
let imageDataDict:[String: UIImage] = ["image": image]
// Post a notification
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "notificationName"), object: nil, userInfo: imageDataDict)
// `default` is now a property, not a method call
// Register to receive notification in your class
NotificationCenter.default.addObserver(self, selector: #selector(self.showSpinningWheel(_:)), name: NSNotification.Name(rawValue: "notificationName"), object: nil)
// Handle notification
func showSpinningWheel(_ notification: NSNotification) {
print(notification.userInfo ?? "")
if let dict = notification.userInfo as NSDictionary? {
if let id = dict["image"] as? UIImage {
// Do something with your image
}
}
}
对于Swift 4
let imageDataDict:[String: UIImage] = ["image": image]
// Post a notification
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "notificationName"), object: nil, userInfo: imageDataDict)
// `default` is now a property, not a method call
// Register to receive notification in your class
NotificationCenter.default.addObserver(self, selector: #selector(self.showSpinningWheel(_:)), name: NSNotification.Name(rawValue: "notificationName"), object: nil)
// Handle notification
@objc func showSpinningWheel(_ notification: NSNotification) {
print(notification.userInfo ?? "")
if let dict = notification.userInfo as NSDictionary? {
if let id = dict["image"] as? UIImage {
// Do something with your image
}
}
}
在Swift中传递数据有很多解决方案。
向前传递数据
我最喜欢的两种转发数据的方式是依赖注入(DI)和属性观察者
依赖注入
class CustomView : UIView {
init(_ with model : Model) {
// Do what you want with data
}
}
财产观察员
class CustomView : UIView {
var model : Model? {
didSet {
// Do what you want with data after assign data to model
}
willSet {
// Do what you want with data before assign data to model
}
}
}
向后传递数据
还喜欢将数据传递到上一个VC/视图的方法:
协议和代表
protocol CustomViewDelegate : class {
func addItemViewController(_ with data: Model?)
}
weak var delegate : CustomViewDelegate?
class AnotherCustomView: UIView {
let customView = AnotherCustomView()
init() {
customView.delegate = self
}
}
extention AnotherCustomView : CustomViewDelegate {
func addItemViewController(_ with data: Model?) {
// Do what you want with data
}
}
关闭
class AnotherCustomView : UIView {
init(addItem: @escaping (_ value : Model?) -> ()) {
// Do what you want with data
}
}
class CustomView : UIView {
init() {
let customView = AnotherCustomView { [weak self] model in
// Do what you want with data
}
}
}