boppa boppa - 3 months ago 8
Swift Question

Data returning as nil after passing through protocol to next view controller

I am presenting a view controller modally as a custom popover from a table view using

didSelectRowAtIndexPath
and
prepareForSegue
. However, the data on the next view controller is returning nil. I have narrowed the problem down to passing the data through the protocol itself. Below I will include the relevant code for both view controllers and the log.

First View Controller:

protocol barTableViewControllerDelegate {
func acceptData(data: AnyObject!)
}

class barTableViewController: UITableViewController, CLLocationManagerDelegate {
var delegate: barTableViewControllerDelegate?
var data: AnyObject?

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("yes")
let classIndexPath = self.tableView.indexPathForSelectedRow!
print(classIndexPath.row)
print("yes2")
let selectedClass = names[classIndexPath.row]
print("yes3")
print(names[classIndexPath.row])
self.delegate?.acceptData(selectedClass)
self.performSegueWithIdentifier("showAd", sender: self)
}


override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "showAd") {
/* if let objIndexPath = self.tableView.indexPathForSelectedRow?.row {
let obj = queryArray[objIndexPath]
let navVC = segue.destinationViewController as! UINavigationController
let detailVC = navVC.topViewController as! DetailViewController
detailVC.post = obj */
print("is segue working")
let popOverVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("adPopUp") as! PopUpViewController
self.addChildViewController(popOverVC)
popOverVC.view.frame = self.view.frame
self.view.addSubview(popOverVC.view)
popOverVC.didMoveToParentViewController(self)
print("segue working")
}
}


Second View Controller:

class PopUpViewController: UIViewController {

func acceptData(data: AnyObject!) {
self.post = data! as! String
}


override func viewDidLoad() {
super.viewDidLoad()
print("here")
print(post)
print(self.post)
print("here2")
}
}


log screenshot

The last log printed is
here.
Stops at
print(post)
.
I don't think I have to declare data in the second view controller?

Answer

If you're going forward, you don't need the protocol. You can simply set the next view controller's variable in prepareForSegue

class barTableViewController: UITableViewController, CLLocationManagerDelegate {        

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        let classIndexPath = self.tableView.indexPathForSelectedRow!
        let selectedClass = names[classIndexPath.row]
        self.performSegueWithIdentifier("showAd", sender: self)
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if(segue.identifier == "showAd") {
            let popOverVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("adPopUp") as! PopUpViewController

            popOverVC.data = selectedClass  // <-- Set the variable in the next VC

            self.addChildViewController(popOverVC)
            popOverVC.view.frame = self.view.frame
            self.view.addSubview(popOverVC.view)
            popOverVC.didMoveToParentViewController(self)
        }
    }
}

class PopUpViewController: UIViewController {

    var data: String!

    override func viewDidLoad() {
        super.viewDidLoad()

        if let passedData = data {
            self.post = passedData
        }
    }
}