[英]using delegates/protocols to pass data to third party view controller
I have 3 view controllers: http://i58.tinypic.com/2envu2x.png 我有3个视图控制器: http : //i58.tinypic.com/2envu2x.png
View Controller 1 is the first, and it segues to view controller 2. view controller 3 is a child view of view controller 2, as there is a container view in view controller2. 视图控制器1是第一个,并且它被视为视图控制器2.视图控制器3是视图控制器2的子视图,因为在视图控制器2中存在容器视图。 I need to pass data from view controller 1 to view controller 3. Using traditional delegates and protocols, i have to actually segue to view controller 3 in order to pass data to it.
我需要将数据从视图控制器1传递到视图控制器3.使用传统的委托和协议,我必须实际上看到控制器3才能将数据传递给它。 But the segue is from the first view controller to the container view (second view controller), not the third.
但是segue是从第一个视图控制器到容器视图(第二个视图控制器),而不是第三个。 How can I modify the delegate/protocol to achieve this?
如何修改委托/协议来实现这一目标?
Here is the code for my first view controller (it has a table view so I am putting the protocol in the table cell): 这是我的第一个视图控制器的代码(它有一个表视图,所以我将协议放在表格单元格中):
import UIKit
protocol DataEnteredDelegate {
func userDidCHooseClass(classChose: String)
}
class FirstTableViewCell: UITableViewCell {
var delegate:DataEnteredDelegate?
@IBAction func buttonTapped(sender: AnyObject) {
let string = "che107"
self.delegate?.userDidCHooseClass(string)
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
Here is the code for view controller 3, the view controller that I want to receive the string: 这是视图控制器3的代码,我想要接收字符串的视图控制器:
import UIKit
class SecondTBC: UITableViewController, DataEnteredDelegate {
var stringThing = String()
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Potentially incomplete method implementation.
// Return the number of sections.
return 0
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.
return 0
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath) as! firstCell
return cell
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "segue1" {
var otherController = FirstTableViewCell()
otherController.delegate = self
}
}
func userDidCHooseClass(classChose: String) {
stringThing = classChose
}
} }
To pass data between two otherwise unconnected View Controllers you'll need to use: 要在两个未连接的View Controller之间传递数据,您需要使用:
presentingViewController!.dismissViewControllerAnimated(true, completion: nil)
and transmit your data via viewWillDisappear like this: 并通过viewWillDisappear传输您的数据,如下所示:
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
if self.isBeingDismissed() {
self.delegate?.acceptData(textFieldOutlet.text)
}
}
I've posted a tutorial , that includes a working project file that you can download and inspect. 我发布了一个教程 ,其中包含一个可以下载和检查的工作项目文件。
Heres an example of the pattern in context. 下面是上下文中模式的一个例子。
// place the protocol in the view controller that is being presented
protocol PresentedViewControllerDelegate {
func acceptData(data: AnyObject!)
}
class PresentedViewController: UIViewController {
// create a variable that will recieve / send messages
// between the view controllers.
var delegate : PresentedViewControllerDelegate?
// another data outlet
var data : AnyObject?
@IBOutlet weak var textFieldOutlet: UITextField!
@IBAction func doDismiss(sender: AnyObject) {
if textFieldOutlet.text != "" {
self.presentingViewController!.dismissViewControllerAnimated(true, completion: nil)
}
}
override func viewDidLoad() {
super.viewDidLoad()
print("\(data!)")
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
if self.isBeingDismissed() {
self.delegate?.acceptData(textFieldOutlet.text)
}
}
}
class ViewController: UIViewController, PresentedViewControllerDelegate {
@IBOutlet weak var textOutlet: UILabel!
@IBAction func doPresent(sender: AnyObject) {
let pvc = storyboard?.instantiateViewControllerWithIdentifier("PresentedViewController") as! PresentedViewController
pvc.data = "important data sent via delegate!"
pvc.delegate = self
self.presentViewController(pvc, animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
}
func acceptData(data: AnyObject!) {
self.textOutlet.text = "\(data!)"
}
}
I have found an answer: using global variables. 我找到了答案:使用全局变量。
Here is what I did: 这是我做的:
In my first view controller (the view controller that is sending the string), I made a global variable above the class definition, like this: 在我的第一个视图控制器(发送字符串的视图控制器)中,我在类定义之上创建了一个全局变量,如下所示:
import UIKit
var chosenClass = String()
class EntryViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
// other code here that isn't relevant to the topic at hand
}
then, in the same view controller, when a table cell was selected, I did this: 然后,在同一视图控制器中,当选择表格单元格时,我这样做:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var row = self.tableView.indexPathForSelectedRow()?.row
chosenClass = array2[row!]
}
where 哪里
array2[row!]
is the string that I am wanting to pass. 是我想要通过的字符串。
in the third view controller, I made another string local variable, string to receive : 在第三个视图控制器中,我创建了另一个字符串局部变量,字符串接收:
import UIKit
import Parse
import ParseUI
import Foundation
class FirstTableViewController: PFQueryTableViewController {
@IBOutlet weak var navigationBarTop: UINavigationItem!
var stringToRecieve = String()
}
In the viewDidLoad of the third view controller, I simply put: 在第三个视图控制器的viewDidLoad中,我简单地说:
stringToRecieve = chosenClass
and that is it. 就是这样。 No additional code was needed for the second view controller, where the container view is.
容器视图所在的第二个视图控制器不需要其他代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.