如何将数据从孩子传递给父视图控制器? 迅速

我创build了一个活动,当其中一个文本字段点击它会popup一个小孩(警报对话框)与产品列表,但是当我单击列表中的一个项目时,我不能显示在警报解散后的文本字段上。

这是父视图

import Foundation import UIKit class ViewAward: UIViewController{ @IBOutlet var tfMCN: UITextField! @IBOutlet var tfAmount: UITextField! @IBOutlet var tfProduct: UITextField! @IBOutlet var tfTotal: UITextField! override func viewDidLoad() { super.viewDidLoad() let rightAddBarButtonItem:UIBarButtonItem = UIBarButtonItem(title: "Send", style: UIBarButtonItemStyle.Plain, target: self, action: #selector(ViewAward.searchTapped)) self.navigationItem.setRightBarButtonItems([rightAddBarButtonItem], animated: true) let state = String(ViewPopUpProduct.Product.ProductDescription) print("My view state:"+state) self.tfProduct.text = state tfProduct.addTarget(self, action: #selector(ViewAward.productTapped), forControlEvents: UIControlEvents.TouchDown) } func searchTapped(sender:UIButton) { let alertController = UIAlertController( title: "Award", message:"Award successfully posted!", preferredStyle: UIAlertControllerStyle.Alert) alertController.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default,handler: nil)) self.presentViewController(alertController, animated: true, completion: nil) } func productTapped(textfield: UITextField){ //tfProduct.endEditing(true) tfProduct.resignFirstResponder() let popOverVC = UIStoryboard(name:"Main",bundle:nil).instantiateViewControllerWithIdentifier("sbPopUpID") as! ViewPopUpProduct self.addChildViewController(popOverVC) popOverVC.view.frame = self.view.frame self.view.addSubview(popOverVC.view) popOverVC.didMoveToParentViewController(self) } } 

而当用户点击这些项目时

 import UIKit class ViewPopUpProduct: UIViewController { @IBOutlet var tableView: UITableView! var productDescription = ["Product 1","Product 2","Product 3"] var productID = ["prdct1","prdct2","prdct3"] // Global Variables struct Product { static var ProductID = String() static var ProductDescription = String() } override func viewDidLoad() { super.viewDidLoad() self.showAnimate() self.view.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.4) // Do any additional setup after loading the view. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } @IBAction func cancelPopUp(sender: AnyObject) { self.removeAnimate() } func showAnimate() { self.view.transform = CGAffineTransformMakeScale(1.3, 1.3) self.view.alpha = 0.0; UIView.animateWithDuration(0.25, animations: { self.view.alpha = 1.0 self.view.transform = CGAffineTransformMakeScale(1.0, 1.0) }); } func removeAnimate() { UIView.animateWithDuration(0.25, animations: { self.view.transform = CGAffineTransformMakeScale(1.3, 1.3) self.view.alpha = 0.0; }, completion:{(finished : Bool) in if (finished) { self.view.removeFromSuperview() } }); } //Mark - Table View func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.productID.count } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = self.tableView.dequeueReusableCellWithIdentifier("cell",forIndexPath: indexPath) as! ProductViewCell cell.productLabel.text = productDescription[indexPath.row] return cell } func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { tableView.deselectRowAtIndexPath(indexPath, animated: true) Product.ProductID = String(productID[indexPath.row]) Product.ProductDescription = String(productDescription[indexPath.row]) self.removeAnimate() } } 

你可以使用协议/委托

这是一个非常非常简单的解释,没有bs: https : //www.youtube.com/watch?v = guSYMPaXLaw

或者你也可以使用NSNotificationCenter

你可以做这样的事情:

“发件人”视图控制器会做

 let nc = NSNotificationCenter.defaultCenter() nc.postNotificationName("printValue", object: nil, userInfo: ["value" : "Pass Me this string"]) 

接收者视图控制器然后可以收听通知。

 let nc = NSNotificationCenter.defaultCenter() nc.addObserver(self, selector: #selector(printValue), name: "printValue", object: nil) func printValue(notification:NSNotification) { let userInfo:Dictionary<String,String> = notification.userInfo as! Dictionary<String,String> let item = userInfo["value"]! as String print(item,self) } 

我通常使用闭包来达到这个目的。 比代表们更简单,更简洁:

 class MainViewController: UIViewController { func showChildViewController() { guard let vc = storyboard?.instantiateViewControllerWithIdentifier("ChildViewController") as? ChildViewController else { return } vc.didSelectItem = { [weak self](item) in if let vc = self { // Do something with the item. } } presentViewController(vc, animated: true, completion: nil) } } class ChildViewController: UIViewController { var didSelectItem: ((item: Item) -> Void)? @IBAction func buttonPressed() { didSelectItem?(item: <#your item goes here#>) } } 

有几种方法可以实现callbackfunction来传递数据。

  • 代表
  • 使用阻止callback
  • 邮政通知

但我会build议使用委托,这是最好的方式,邮政通知也是一种方式,但我不想更喜欢。

  1. 我的第一select是自定义代表,它更快更完美。 (如果你可以使用闭包作为callback,那么这应该是完美的。select委托来解释一下你的代码。)

  2. 请尽可能避免使用NSNotificationCenter,因为在使用这个软件时有太多的事情要处理,而且比代表慢一些。 你也可能很容易陷入错误。

现在,这是我的代码。

1.子ViewController安装。

  // TrendingProductPageViewController.swift // buddyiOSApp // // Created by Tuhin Samui on 5/21/16. // Copyright © 2016 Buddy. All rights reserved. // import UIKit protocol TrendingProductsCustomDelegate: class { //Setting up a Custom delegate for this class. I am using `class` here to make it weak. func sendDataBackToHomePageViewController(categoryToRefresh: String?) //This function will send the data back to origin viewcontroller. } class TrendingProductPageViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, NetworkReachabilityDelegate { @IBOutlet weak var productListTableView: UITableView! //Having a tableview outlet here from storyboard itself. BTW not going to explain with tableView delegate and datasource, Sorry..:( weak var customDelegateForDataReturn: TrendingProductsCustomDelegate? //Please use weak reference for this to manage the memory issue. func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { let rowNumberFromTable: Int = indexPath.row //Getting the index of the selected cell. let dataToSendBack = moreMenuTableData[rowNumberFromTable] as! String //This is an array which contains the data for the tableview. Getting the exact data which is selected on the table. customDelegateForDataReturn?.sendDataBackToHomePageViewController?(dataToSendBack) //Now sending the selected data back to parent viewController using the custom delegate which I made before. presentingViewController?.dismissViewControllerAnimated(true, completion: nil) //Dismissing the viewController here. } 

2.父ViewController代码在这里。

 class HomePageViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, TrendingProductsCustomDelegate, UINavigationControllerDelegate{ //Adding the protocol here as `TrendingProductsCustomDelegate` @IBAction func topTrendingProductsBtnAction(sender: UIButton) { //Normal IBAction of UIButton as you are using. let trendingProductsPageForAnimation = storyboard!.instantiateViewControllerWithIdentifier("showTrendingProductpage") as! TrendingProductPageViewController //You can understand this right. Same as yours. trendingProductsPageForAnimation.customDelegateForDataReturn = self //Setting up the custom delegate for this class which I have written on the presenting class. trendingProductsPageForAnimation.modalPresentationStyle = UIModalPresentationStyle.FullScreen presentViewController(trendingProductsPageForAnimation, animated: true, completion: nil) //Same as yours. } func sendDataBackToHomePageViewController(categoryToRefresh: String?) { //Custom delegate function which was defined inside child class to get the data and do the other stuffs. if categoryToRefresh != nil { print("Got the data is \(categoryToRefresh)") } } } 

希望这有助于。 对不起,有任何错误。