简体   繁体   中英

View Controller delegate returns nil

My code is below. When I press the 'Done' or 'Cancel' buttons, it doesn't work as I want. I did some debugging, and delegate is nil even though I set it. Please help - thanks.

class ViewController: UIViewController,EditViewControllerDelegate {

    @IBOutlet weak var label: UILabel!

    //页面跳转时
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "EditView" {
            //通过seque的标识获得跳转目标
            let controller = segue.destinationViewController as! EditViewController
            //设置代理
            controller.delegate = self
            //将值传递给新页面
            controller.oldInfo = label.text
        }
    }

    func editInfo(controller:EditViewController, newInfo:String){

        label.text = newInfo
        //关闭编辑页面
        controller.presentingViewController!.dismissViewControllerAnimated(true, completion: nil)
    }

    func editInfoDidCancer(controller:EditViewController){

        //关闭编辑页面
        controller.presentingViewController!.dismissViewControllerAnimated(true, completion: nil)
    }
}

import UIKit

protocol EditViewControllerDelegate {
    func editInfo(controller:EditViewController, newInfo:String)
    func editInfoDidCancer(controller:EditViewController)
}

class EditViewController: UIViewController {

    @IBOutlet weak var textField: UITextField!

    var delegate:EditViewControllerDelegate?

    var oldInfo:String?

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        if oldInfo  != nil{
            textField.text = oldInfo
        }
    }

    @IBAction func done(sender: AnyObject) {
        delegate?.editInfo(self, newInfo: textField.text!)
    }

    @IBAction func cancel(sender: AnyObject) {
        delegate?.editInfoDidCancer(self)
    }
}

I'm not able to tell from your code how you are handling the opening of EditViewController from your ViewController .

I'm guessing that your prepareForSegue:sender: is not getting called resulting in the delegate not getting set. To fix this, you will need to add a performSegueWithIdentifier:sender: call at the point where the segue needs to happen as in

self.performSegueWithIdentifier("EditView", sender: self)

You should replace whatever code is performing the opening of EditViewController with that call.

I have an app the uses showViewController:sender: to open up a second view controller from the first one even though there is a Show segue defined in my storyboard. The segue in my storyboard doesn't get used in that case and prepareForSegue:sender: is never called as a result.

If I replace my

showViewController(myVC, sender: self)

with

performSegueWithIdentifier("mySegue", sender: self)

then prepareForSegue:sender: will get called. If I am setting a delegate, like you are, in prepareForSegue:sender: , the delegate will get set before the segue happens.

Try this,

class ViewController: UIViewController,EditViewControllerDelegate {
var controller: EditViewController?
    @IBOutlet weak var label: UILabel!

    //页面跳转时
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "EditView" {
            //通过seque的标识获得跳转目标
            controller = segue.destinationViewController as! EditViewController
            //设置代理
            controller.delegate = self
            //将值传递给新页面
            controller.oldInfo = label.text
        }
    }

    func editInfo(controller:EditViewController, newInfo:String){

        label.text = newInfo
        //关闭编辑页面
        controller.presentingViewController!.dismissViewControllerAnimated(true, completion: nil)
    }

    func editInfoDidCancer(controller:EditViewController){

        //关闭编辑页面
        controller.presentingViewController!.dismissViewControllerAnimated(true, completion: nil)
    }
}

import UIKit

protocol EditViewControllerDelegate {
    func editInfo(controller:EditViewController, newInfo:String)
    func editInfoDidCancer(controller:EditViewController)
}

class EditViewController: UIViewController {

    @IBOutlet weak var textField: UITextField!

    var delegate:EditViewControllerDelegate?

    var oldInfo:String?

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        if oldInfo  != nil{
            textField.text = oldInfo
        }
    }

    @IBAction func done(sender: AnyObject) {
        delegate?.editInfo(self, newInfo: textField.text!)
    }

    @IBAction func cancel(sender: AnyObject) {
        delegate?.editInfoDidCancer(self)
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM