ios 从视图控制器 Xcode 传回数据
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25522912/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Passing data back from view controllers Xcode
提问by B_s
A couple of weeks ago I asked thisquestion and got a very detailed explanation. Now I would like to pass data back to the first ViewController but I keep getting stuck using the same method. I have a modal of the first VC to the second, where I would like to edit an array of strings, which will be showed on the first view again. So on my first view I have an array of data, which should be passed to the second so edit fields show the current information after which the user has to be able to edit the contents of the array and pass that data back to the first where it is shown on labels. I'm using Swift.
几周前我问了这个问题并得到了非常详细的解释。现在我想将数据传递回第一个 ViewController,但我一直在使用相同的方法卡住。我有第一个 VC 到第二个 VC 的模式,我想在其中编辑一个字符串数组,这些字符串将再次显示在第一个视图中。所以在我的第一个视图中,我有一个数据数组,它应该传递给第二个,因此编辑字段显示当前信息,之后用户必须能够编辑数组的内容并将该数据传递回第一个它显示在标签上。我正在使用斯威夫特。
My code:
我的代码:
(in ViewController.swift:)
(在 ViewController.swift 中:)
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
let secondVC = segue.destinationViewController as SecondViewController
secondVC.namesPlayers = self.namesPlayers
}
(in SecondViewController.swift:)
(在 SecondViewController.swift 中:)
override func viewDidLoad() {
super.viewDidLoad()
labelFirstPlayer.text = namenSpelers[0]
}
Thank you
谢谢
回答by derdida
You need to use a delegate. Here is an example how do use a delegate in Swift.
您需要使用委托。这是一个如何在 Swift 中使用委托的示例。
On your first ViewController, set your delegate when you load the second VC:
在您的第一个 ViewController 上,在加载第二个 VC 时设置您的委托:
For example, if you are using the Storyboard Editor:
例如,如果您使用的是故事板编辑器:
var secondViewController = (segue.destinationViewController.visibleViewController as MySecondViewControllerClass)
secondViewController.delegate = self
Write a Protocol and define a func to write you values back
写一个协议并定义一个函数来写回你的值
For example, create a file called "Protocol.swift" and write something like that:
例如,创建一个名为“Protocol.swift”的文件并编写如下内容:
protocol writeValueBackDelegate {
func writeValueBack(value: String)
}
Add the function to your FirstViewController
将该功能添加到您的 FirstViewController
func writeValueBack(value: String) {
// Or any other function you need to transport data
}
And to your ViewControllerClass
和你的 ViewControllerClass
class ViewController: UIViewController, writeValueBackDelegate
The above line will not work if you have not implemented all of the methods in ViewController
that you defined in your protocol file.
如果您没有实现ViewController
您在协议文件中定义的所有方法,上面的行将不起作用。
Go to the Second View Controller, and add the delegate here:
转到第二个视图控制器,并在此处添加委托:
class SecondViewController: ViewController {
// Delegate for FirstViewController
// Declare as weak to avoid memory cycles
weak var delegate: writeValueBackDelegate?
}
On your Second View Controller, you can now use this to call the func in the first View Controller an pass data.
在您的第二个视图控制器上,您现在可以使用它来调用第一个视图控制器中的 func 并传递数据。
delegate?.writeValueBack("That is a value")
回答by Opus1217
I'm confused by the answer using delegates, because it seems to me needlessly complicated. Here's what I did to pop-up an Add Player dialog in my card game, and pass the results back to the calling view controller.
我对使用委托的答案感到困惑,因为在我看来它不必要地复杂。这是我在纸牌游戏中弹出添加玩家对话框并将结果传递回调用视图控制器的操作。
Add delegate protocol (in my case in my Extensions/Protocols file)
添加委托协议(在我的情况下在我的扩展/协议文件中)
protocol ReturnPlayerInfoDelegate {
func returnPlayerInfo(playerName : String, playerType : Player.Type)
}
Then I added my reference (as a class var) to the delegate in the CALLED View Controller. Note this didn't require my subclassing my caller, or adding the protocol to my called View Controller:
然后我将我的引用(作为类变量)添加到 CALLED 视图控制器中的委托。请注意,这不需要我对调用者进行子类化,也不需要将协议添加到我调用的视图控制器中:
class AddPlayerViewController : UIViewController {
static var delegate : ReturnPlayerInfoDelegate!
and called the delegate in my Ok button handler:
并在我的 Ok 按钮处理程序中调用委托:
@IBAction func onOK(sender: UIButton) {
AddPlayerViewController.delegate.returnPlayerInfo(mPlayerName.text!, playerType: mPlayerTypeActual)
dismissViewControllerAnimated(true, completion: nil)
}
Now I implemented the delegate in the CALLING ViewController:
现在我在 CALLING ViewController 中实现了委托:
class FiveKings : UIViewController, UIGestureRecognizerDelegate, UIPopoverPresentationControllerDelegate ,UITextViewDelegate , ReturnPlayerInfoDelegate {
...
override func viewDidLoad() {
super.viewDidLoad()
AddPlayerViewController.delegate = self
...
func returnPlayerInfo(playerName : String, playerType : Player.Type) {
mGame.addPlayer(playerName, newPlayerClass: playerType, fKActivity: self)
}
This works very nicely. Do you see any problems with my implementation?
这很好用。你看到我的实施有什么问题吗?
回答by RviOS
Hope this will help you
希望能帮到你
This the second controller from where you want to return data to pushed. SecondView.swift
这是第二个控制器,您希望从中返回数据以进行推送。 SecondView.swift
@objc protocol returnDataProtocol {
func returnStringData(myData: String)
}
class SecondView: UIViewController {
weak var delegate: returnStringData?
@IBAction func readyButtonPressed(sender: AnyObject) {
// Do what you want here
delegate?.returnStringData("Euro/Dollar etc....")
// this function is exist in first view controller
}
}
First view ViewController firstView.swift
第一个视图 ViewController firstView.swift
class firstView: UIViewController, returnDataProtocol {
// this function will call to second view. You can use here push method, if you are using navigation controller.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "mySegue" { // your identifier here
let controller = segue.destinationViewController as! MyPopOverController
controller.delegate = self
}
}
// here you will get return value from second view controller class
func returnStringData(myData: String){
print(myData)
}
}