swiftprotocolsdelegationdata-sharing

How do you update the value you delegated from one class to the other?


I'm having an issue with Delegating. I'm relatively new to the concept, and but conceptually I get it and it's importance. I'm just having trouble using it. I can't seem to pass data from one class to the other. I know there are existing examples of delegation out there on stack overflow but they aren't quite capturing my misunderstanding. I get the use of protocols, delegation, and calling it in a class. I believe there just some small nuance that I'm missing... And it's visible in the lack of functionality in my code

//my protocol:

protocol StingHolder {
    func StringPasser(ThisText text: String)
}

Creating the delegate protocol relation, places data to be passed then dismisses the View Controller


// my classes for placing data to be passed

class changeLabel: UIViewController,UITextFieldDelegate{

   var Delegate: StingHolder?


    @IBOutlet weak var TexrBeingPassed: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        TexrBeingPassed.delegate = self
        // Do any additional setup after loading the view.
    }



    @IBAction func ButtonPassingDataOtherView(_ sender: Any) {

            Delegate?.StringPasser(ThisText: TexrBeingPassed.text!)
            dismiss(animated: true, completion: nil)


    }
}

Creates an instance of the change lable class and its delegate and sets itself to be the delegate *supposedly changes the label, but It doesn't

///class to receive data


class ViewController: UIViewController{
    @IBOutlet weak var LableName: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

        var lableChange = changeLabel()
        lableChange.Delegate = self

        // Do any additional setup after loading the view.
    }


    @IBAction func EditController(_ sender: Any) {

        var storyBoard = UIStoryboard(name: "Test", bundle: nil)
        var ViewController = storyBoard.instantiateViewController(withIdentifier: "TestView")
        self.present(ViewController, animated: true, completion: nil)
    }


}

inherits the protocol and tells it to change the label to whatever the changelabel class delegate has passes

// extension view controller inheriting the protocol

extension ViewController : StingHolder{

    func StringPasser(ThisText text: String){

        print("Delegate is working")
        LableName.text = text
        ///
    }  
}

I want the one view controller to edit the text label of another view controller


Solution

  • The object which you have self as a delegate of, is not the same object presented on the screen.

    override func viewDidLoad() {
        super.viewDidLoad()
    
        // "labelChange.delegate" is set...
        var lableChange = changeLabel()
        lableChange.Delegate = self
    
        // Do any additional setup after loading the view.
    }
    
    
    @IBAction func EditController(_ sender: Any) {
    
        var storyBoard = UIStoryboard(name: "Test", bundle: nil)
        // but "ViewController" is presented
        var ViewController = storyBoard.instantiateViewController(withIdentifier: "TestView")
        self.present(ViewController, animated: true, completion: nil)
    }
    

    labelChange and ViewController are two different, independent objects. One created by calling init directly, and the other created by calling storyBoard.instantiateViewController. You should set the delegate of the latter instead:

    override func viewDidLoad() {
        super.viewDidLoad()
    
        // "labelChange.delegate" can be deleted
    }
    
    
    @IBAction func EditController(_ sender: Any) {
    
        var storyBoard = UIStoryboard(name: "Test", bundle: nil)
        if let ViewController = storyBoard.instantiateViewController(withIdentifier: "TestView") as? labelChange {
            ViewController.delegate = self
            self.present(ViewController, animated: true, completion: nil)
        }
    }