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

В кода по-долу имам ViewController("SenderViewController"), който предава съобщение на главния ViewController, когато се докосне бутон. Това, което не разбирам напълно, е как методът messageData() в главния ViewController знае кога да изслуша съобщението.

Може ли някой да ми обясни какво задейства метода messageData() в основния ViewController?

SenderViewController:

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 на 'myself', точно на екземпляр на 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)  


  }  
}  

Главен контролер за преглед

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