如何使用协议/代理在UIViewControllers之间传递数据

10
在下面的代码中,我有一个名为“SenderViewController”的 ViewController,当点击按钮时会向主ViewController传递一条消息。但我不完全了解的是,主ViewController中的方法是如何知道何时监听这个消息。
请问是什么触发了主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!)  
        }  
    }  
}  

主视图控制器:

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)"  
    }  
} 

非常感谢!


1
SenderViewController 中的 func sendData 中调用 self.delegate?.messageData,正在执行它。 - iphonic
1
跟着这个教程,你会找到答案的 - http://www.tutorialspoint.com/ios/ios_delegates.htm - Anupam Mishra
使用委托传递数据 Swift 4.0:https://iosdevcenters.blogspot.com/2017/11/what-is-protocol-how-to-pop-data-using.html - Bhadresh
5个回答

6

对象并不会准确地等待方法调用,它们只是静静地坐在那里,等待被调用。

这行代码

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

你的SenderViewController中有一个函数调用。(术语方法和函数几乎可以互换,尽管方法通常用于对象的函数。)它调用了ViewController中的函数messageData


3

SenderViewController中:

当您点击按钮时,会调用sendData方法。在此方法中,您要求delegate调用其messageData方法。委托属性声明为SenderViewControllerDelegate类型,因此您可以这样做(请参见此协议定义)。

ViewController(第一个视图控制器)中:

在打开第二个视图控制器之前,在goToView方法中,您将SenderViewControllerdelegate属性设置为“我自己”,即ViewController的确切实例,因为您通过实现messageData方法声明了它符合协议SenderViewControllerDelegate。因此,ViewController现在保存为SenderViewController中的delegate属性,并且可以用于调用messageData


3
在从MainViewController中展示SenderViewController时,您将委托设为self。因此,每当您在SenderViewController中调用委托方法时,
self.delegate?.messageData(inputMessage.text!)

MainViewController的以下方法将作为回调函数。

func messageData(data: AnyObject) {  
        self.showData.text = "\(data)"  
    } 

非常感谢您的输入。 - fs_tigre

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

0
@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": "test@gmail.com"] 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"])  

    }  
} 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接