Как передавать данные между UIViewControllers с протоколами/делегатами

В приведенном ниже коде у меня есть ViewController("SenderViewController"), который передает сообщение основному ViewController при нажатии кнопки. Чего я не совсем понимаю, так это того, как метод messageData() в основном ViewController узнает, когда слушать сообщение.

Может кто-нибудь объяснить мне, что вызывает метод messageData() в основном ViewController?

Сендервиевконтроллер:

import UIKit  
protocol SenderViewControllerDelegate {  
    func messageData(data: AnyObject)  
}  
class SenderViewController: UIViewController {  
    @IBOutlet weak var inputMessage: UITextField!  
     var delegate: SenderViewControllerDelegate?  

    @IBAction func sendData(sender: AnyObject) {  
        /  
        if inputMessage.text != ""{  
            self.presentingViewController!.dismissViewControllerAnimated(true, completion: nil)  
            self.delegate?.messageData(inputMessage.text!)  
        }  
    }  
}  

Основной ViewController:

import UIKit  
class ViewController: UIViewController, SenderViewControllerDelegate{  
    @IBOutlet weak var showData: UILabel!  

    override func viewDidLoad() {  
        super.viewDidLoad()  
    }  

    @IBAction func goToView(sender: AnyObject) {  
        let pvc = storyboard?.instantiateViewControllerWithIdentifier("senderViewController") as! SenderViewController  
        pvc.delegate = self  
        self.presentViewController(pvc, animated:true, completion:nil)  
    }  

   // What triggers this method, how it know when to listen? 
    func messageData(data: AnyObject) {  
        self.showData.text = "\(data)"  
    }  
} 

Большое спасибо!


person fs_tigre    schedule 02.08.2016    source источник
comment
Этот вызов self.delegate?.messageData из func sendData в SenderViewController выполняет его.   -  person iphonic    schedule 02.08.2016
comment
Следуйте этому руководству, и вы получите ответ — tutorialspoint.com/ios/ios_delegates.htm   -  person Anupam Mishra    schedule 02.08.2016
comment
Передача данных с помощью делегата swift 4.0: iosdevcenters.blogspot.com/2017/11/   -  person Bhadresh    schedule 02.11.2017


Ответы (4)


Объекты точно не прослушивают вызовы методов. Они сидят там, ожидая вызова.

Линия

self.delegate?.messageData(inputMessage.text!)

Из вашего SenderViewController это вызов функции. (Термины метод и функция в значительной степени взаимозаменяемы, хотя method обычно используется для функций объектов.) Он вызывает функцию messageData в ViewController.

person Duncan C    schedule 02.08.2016

Представляя SenderViewController от MainViewController, вы назначаете делегата self. Поэтому всякий раз, когда вы вызываете метод делегата в SenderViewController

self.delegate?.messageData(inputMessage.text!)

следующий метод MainViewController будет действовать как обратный вызов

func messageData(data: AnyObject) {  
        self.showData.text = "\(data)"  
    } 
person Mohammed Shakeer    schedule 02.08.2016
comment
Большое спасибо за ваш вклад. - person fs_tigre; 02.08.2016

In SenderViewController:

Когда вы нажимаете кнопку, вы вызываете метод sendData. В этом методе вы просите delegate вызвать его метод messageData. Свойство делегата объявлено как тип SenderViewControllerDelegate, поэтому вы можете это сделать (см. определение этого протокола).

В ViewController (контроллер первого вида):

Перед тем, как открыть второй контроллер представления, в методе goToView вы настраиваете свойство delegate из SenderViewController на «себя», на точный экземпляр ViewController, поскольку вы объявили, что он подтверждает протокол SenderViewControllerDelegate путем реализации метода messageData. Таким образом, ViewController теперь сохраняется как свойство delegate в SenderViewController и может использоваться для вызова messageData!

person Shadow Of    schedule 02.08.2016

@IBAction func sendData(sender: AnyObject) {  

    if inputMessage.text != ""{  
        self.delegate?.messageData(inputMessage.text!)  
        self.presentingViewController!.dismissViewControllerAnimated(true, completion: nil)  

    }else{
       //handle here
}

Примечание. Если вам нужно передать несколько данных в mainViewController, используйте словарь для их передачи. то есть

SenderViewController:

import UIKit  
protocol SenderViewControllerDelegate {  
    func messageData(data: [String : Any])  
}  
class SenderViewController: UIViewController {  
    @IBOutlet weak var inputMessage: UITextField!  
    var delegate: SenderViewControllerDelegate?  

    @IBAction func sendData(sender: AnyObject) {  

        let myDict = [ "name": "Name", "age": 21, "email": "[email protected]"] as! [String : Any]

        self.delegate?.messageData(myDict) 
        self.presentingViewController!.dismissViewControllerAnimated(true, completion: nil)  


  }  
}  

Главный ViewController

import UIKit  
class ViewController: UIViewController, SenderViewControllerDelegate{  
    @IBOutlet weak var showData: UILabel!  

    override func viewDidLoad() {  
        super.viewDidLoad()  
    }  

    @IBAction func goToView(sender: AnyObject) {  
        let pvc = storyboard?.instantiateViewControllerWithIdentifier("senderViewController") as! SenderViewController  
        pvc.delegate = self  
        self.presentViewController(pvc, animated:true, completion:nil)  
    }  

   // What triggers this method, how it know when to listen? 
    func messageData(data: [String : Any]) {  
        print(data["name"])  
        print(data["age"])  
        print(data["email"])  

    }  
} 
person Deep    schedule 18.12.2018