如何将数据传回给模态视图控制器

所以通常我会使用委托模式,但这是一个棘手的情况。

视图控制器A呈现 – >视图控制器B呈现 – >视图控制器C.

当用户完成视图控制器C中的步骤时,我将在一次通话中解除B和C.

self.presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil) 

我想将视图控制器C中的数据传递回A.这怎么可能,因为A没有引用C,我怎样才能实现一个委托?

****编辑:这一切都以编程方式完成,所以我不能使用unwind segues

*****解决scheme*******

我发现的最好的解决办法是在VC A中添加一个观察者,并在closuresVC时在VC C中发布该对象:

 self.presentingViewController?.presentingViewController?.dismiss(animated: true) { NotificationCenter.default.post(name: Notification.Name("UpdateKeywords"), object: self.account) } 

不要忘记在deinit()中删除VC A中的观察者

我通常会做的是在b中创build一个引用A,然后在C中创build对引用的引用,然后在传回给A之前,对引用进行更改,然后调用self.presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil)

你可以使用单身devise模式。 为数据声明一个单例类。

 class DatasSingleton{ static let sharedInstance = DatasSingletonSingleton() var datas: int = 0 } 

在C类你设置数据

 class C{ func xyz(){ DatasSingleton.sharedInstance.datas = 6 } } 

在Aclass你可以读取数据

 class A{ func xyz(){ print(DatasSingleton.sharedInstance.datas) } } 

示例代码VC A呈现VC B,VC B呈现VC C,在VC C处input文本,然后调用VC A的方法(此处传输数据),VC C中input的文本如下所示。 ..

希望有所帮助

(Xcode 8.1(8B62):删除故事板,启animation面,清理属性Info.plist中的主要故事板和启animation面,并将AppDelegate.swiftreplace为以下内容)

 import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { self.window = UIWindow(frame: UIScreen.main.bounds) self.window!.rootViewController = Avc() self.window!.makeKeyAndVisible() return true } } class Avc: UIViewController { override func viewDidLoad() { super.viewDidLoad() let b = self.view.addSubviewWithConstraints(["b" : Button(title: "Open B VC")], constraints: ["V:|-10-[b(70)]", "H:|-10-[b]-10-|"])["b"] (b as! Button).action = {() in let bvc = Bvc() bvc.action = self.receiveData self.present(bvc, animated: false,completion: nil) } } func receiveData(data: String?) { print(data) } } class Bvc: UIViewController { var action: ((_ data: String?)->())! override func viewDidLoad() { super.viewDidLoad() let b = self.view.addSubviewWithConstraints(["b" : Button(title: "Open C VC")], constraints: ["V:|-10-[b(70)]", "H:|-10-[b]-10-|"])["b"] (b as! Button).action = {() in let cvc = Cvc() cvc.action = self.action self.present(cvc, animated: false,completion: nil) } } } class Cvc: UIViewController { var action: ((_ data:String?)->())! override func viewDidLoad() { super.viewDidLoad() let t = self.view.addSubviewWithConstraints(["t" : UITextField()], constraints: ["V:|-50-[t(24)]", "H:|-10-[t]-10-|"])["t"] (t as! UITextField).backgroundColor = UIColor.white let b = self.view.addSubviewWithConstraints(["b" : Button(title: "Transfer data to A VC")], constraints: ["V:|-100-[b(90)]", "H:|-10-[b]-10-|"])["b"] (b as! Button).action = {() in self.presentingViewController?.dismiss(animated: true, completion: nil) self.presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil) self.action((t as! UITextField).text) } } } class Button: UIButton { var action: (()->())! init(title: String) { super.init(frame : CGRect.zero) self.setTitle(title, for: UIControlState()) self.addTarget(self, action: #selector(Button.buttonAction(_:)), for: .touchUpInside) } required init?(coder: NSCoder) {super.init(coder: coder)} func buttonAction(_ sender: AnyObject) {if action != nil {action()}} } extension UIView { func addSubviewWithConstraints(_ views: [String : AnyObject], constraints: Array<String>) -> [String : AnyObject] { for (_, view) in views { self.addSubview(view as! UIView) (view as! UIView).translatesAutoresizingMaskIntoConstraints = false } for i in 0 ..< constraints.count {self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: constraints[i], options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views))} return views } }