Joseph Vincent Magtalas Joseph Vincent Magtalas - 3 months ago 25
iOS Question

How to pass data from child to parent view controller? in swift

I created an activity where when one of the text fields clicked it will pop up a child(alert dialog) with list of product but when i click one item on the list I can't display it on the text filed once the alert dismissed.

this is the parent view

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)

}
}


and this when the user clicked on of the items

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()

}

}

Answer

You can use protocols/delegate

Here is a very very straightforward explanation, no bs: https://www.youtube.com/watch?v=guSYMPaXLaw

Or in your situation you can also use NSNotificationCenter

You can do something like this:

The "sender" view controller would do

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

The receiver view controller then can listen to the notification.

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)
}