0

I am trying to understand delegation in Swift better, and I have seen how delegation can be used to pass data from a second view controller back to an initial view controller. But I am confused about how to pass data from the initial view to a second view using delegation. I have initialized an instance of the delegate in my initial view and implement the delegate protocol in the second view, but I am still unsuccessful in passing the data from initial view to second view using delegation. Any advice on what I might be doing wrong would be appreciated! Here is the storyboard view of what my delegation attempt looks like. 1

Initial View Class:

import UIKit

class ViewController: UIViewController {
    
    var data: DataDelegate?
    @IBOutlet weak var text: UITextField!
    @IBOutlet weak var send: UIButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view.
    }
    
    @IBAction func send(_ sender: Any) {
        
        let msg = text.text!
        data?.sendData(data: msg)
        print("SENDING MESSAGE: \(msg)")
    }
}
        
protocol DataDelegate {
    func sendData(data: String)
}

Second View Class:
import UIKit

class RVC: UIViewController, DataDelegate {
    @IBOutlet weak var delegationLabel: UILabel!
    @IBOutlet weak var message: UILabel!
    @IBOutlet weak var back: UIButton!
    
    let vc = ViewController()

    func sendData(data: String) {
        print("DATA SENT")
        let msg = data
        print(msg)
        message.text = data
    
    }
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        print("LOADED")
        vc.data = self

        // Do any additional setup after loading the view.
    }
}
  • How does an instance of `RVC` get created? (Usually, a delegate isn't necessary when going from initial to second.) – Phillip Mills Aug 29 '20 at 19:52
  • 1
    Delegates are useful for moving "backward", not really for moving "forward". The reason is because to move backward, the previous object (initial view controller) had to inject itself in the current object (current view controller) so that the current object could access the previous object. But moving forward, this isn't necessary, because the second view controller is (or should be) within the scope of the previous view controller, so the initial view controller should be able to simply access it. – trndjc Aug 29 '20 at 19:54
  • 1
    Does this answer your question? [Passing Data between View Controllers](https://stackoverflow.com/questions/5210535/passing-data-between-view-controllers) – Joakim Danielson Aug 29 '20 at 21:17
  • How do you run this controllers? your ViewController has a Xib or Storyboard, but you instantiated it like default class. Can you share screen with structure? How your storyboard looks like and where RVC class used? – Alexander Nikolaychuk Aug 30 '20 at 08:05

1 Answers1

2

To solve this problem we need to properly understand the concept of delegate protocol first. Delegate Protocol is basically a sort of communicator which helps to communicate b/w two VC's using specific mentioned methods. When a protocol is defined and its object is created in a VC then it is considered that these are the rules which other VC's must have to follow or implement to communicate with this VC.

In this case(Forward use of delegate) the second VC will send a call back to first VC and demand for data, on receiving the call first VC will then send data to second VC.

First VC(ViewController):

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var text: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func send(_ sender: Any) {
        let secondVC = RVC()
        secondVC.delegate = self
        self.present(secondVC, animated: true)
    }
    
}

extension ViewController: DataDelegate {
    
    func passData() -> String {
        return text.text!
    }
}

Second VC(RVC):

protocol DataDelegate {
    func passData() -> String
}

import UIKit

class RVC: UIViewController {
    
    @IBOutlet weak var message: UILabel!
    
    var delegate: DataDelegate?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setData()
    }
    
    func setData() {
        if let messageDelegate = delegate {
            let messageReceived = messageDelegate.passData()
            message.text = messageReceived
        }
    }
    
}

Hope it solves your problem and help you have some clear understanding of delegation.