2

I have read this thread (and similar others) from bottom to top, but it doesn't fit my needs at all.

I have a UIViewController inside UIPageViewController within a UINavigationController. Navigating to a 2nd ViewController. Navigating to a 3rd ViewController and want to pop back to 2nd ViewController delivering data.

My code currently:

protocol PassClubDelegate {
            func passClub(passedClub: Club)
        }

class My3rdVC: UIViewController {

        var clubs: [Club] = []

        var passClubDelegate: PassClubDelegate?

....

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

        let club = clubs[indexPath.row]
        self.passClubDelegate?.passClub(club)
        navigationController?.popViewControllerAnimated(true)
    }

My 2nd VC:

class My2ndVC: UIViewController, PassClubDelegate {

    var club = Club()

    func passClub(passedClub: Club) {

        SpeedLog.print("passClub called \(passedClub)")
        club = passedClub
    }

passClub is not called. I'm sure it's because I didn't set the delegate to the My2ndVC, but how would I do that? All the solutions I have found wanting me to use a) segue or b) instantiate a My2ndVC new, what doesn't make any sense since it's still in memory and I want to pop back to go back in hierarchy. What am I missing? What are my possibilities? Help is very appreciated.

PS: I'm not using any segues. My3rdVC is called by:

let vc = stb.instantiateViewControllerWithIdentifier("My3rdVC") as! My3rdVC
self.navigationController?.pushViewController(vc, animated: true)
Community
  • 1
  • 1
David Seek
  • 16,783
  • 19
  • 105
  • 136

2 Answers2

5

You can set the delegate of My3rdVC in the prepareForSegue method of My2ndVC.

class My2ndVC: UIViewController, PassClubDelegate {

    ...

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

        super.prepareForSegue(segue, sender: sender)

        switch segue.destinationController {
        case let controller as My3rdVC:
            controller.passClubDelegate = self
        }
    }
}

This is assuming you have created a segue in your storyboard that pushes My3rdVC from My2ndVC onto the navigation controller stack, which I'm assuming you have. So just try simply pasting this prepareForSegue method into My2ndVC and see if it works.

UPDATE

let vc = stb.instantiateViewControllerWithIdentifier("My3rdVC") as! My3rdVC

vc.passClubDelegate = self

navigationController?.pushViewController(vc, animated: true)
Callam
  • 11,409
  • 2
  • 34
  • 32
1

When pop one VC to another you can pass data using protocol by declare delegate variable as static. Here in the following example we pop SecondVC to FirstVC and we pass a string.

class FirstVC: UIViewController,getDataDelegateProtocol {
    @IBOutlet weak var label: UILabel!
    

    override func viewDidLoad() {
        super.viewDidLoad()
        
        SecondVC.delegate = self
    }
    
    func getData(tempStr: String) {
        label.text = tempStr
    }
    
    
    @IBAction func buttonClick(_ sender: UIButton){
        let nav = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SecondVC") as! SecondVC
        self.navigationController?.pushViewController(nav, animated: true)
    }

}

Another View Controller

protocol getDataDelegateProtocol{
    func getData(tempStr: String)
}

class SecondVC: UIViewController {
    
    @IBOutlet weak var label: UILabel!
    static var delegate: getDataDelegateProtocol?

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    
    @IBAction func buttonClick(_ sender: UIButton){
        SecondVC.delegate?.getData(tempStr: "Received data from SecondVC")
        self.navigationController?.popViewController(animated: true)
    }
}
Kunal Nayek
  • 101
  • 2
  • 5