ios 你如何在 Swift 中的视图控制器之间传递数据?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25215476/
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
How do you pass data between view controllers in Swift?
提问by Tomasero
I tried creating global variables and updating the information when the view is loaded but data isn't being rendered.
我尝试在加载视图但未呈现数据时创建全局变量并更新信息。
GLOBAL VARIABLES
全局变量
var viewName:String = ""
var viewDuration:String = ""
var viewPeriod:String = ""
var viewMinAmp:String = ""
var viewMaxAmp:String = ""
var viewStep:String = ""
var viewType:String = ""
Is there a more efficient way of passing information other than having global variables?
除了全局变量之外,还有没有更有效的信息传递方式?
@IBOutlet var txtName: UITextField!
@IBOutlet var txtDuration: UITextField!
@IBOutlet var txtPeriod: UITextField!
@IBOutlet var txtMinAmp: UITextField!
@IBOutlet var txtMaxAmp: UITextField!
@IBOutlet var txtStep: UITextField!
@IBOutlet var txtType: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
setInfo(viewName, duration: viewDuration, period: viewPeriod, minAmp: viewMinAmp, maxAmp: viewMaxAmp, step: viewStep, type: viewType)
}
func setInfo(name: String, duration: String, period: String, minAmp: String, maxAmp: String, step: String, type: String) {
txtName.text = name
txtDuration.text = duration
txtPeriod.text = period
txtMinAmp.text = minAmp
txtMaxAmp.text = maxAmp
txtStep.text = step
txtType.text = type
}
回答by Scott Mielcarski
One solution would be to override prepareForSegue(segue:sender:) from within the view controller which contains the data that you wish to pass to the destination view controller.
一种解决方案是从包含您希望传递给目标视图控制器的数据的视图控制器中覆盖 prepareForSegue(segue:sender:) 。
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if (segue.identifier == "YourSegueName") {
//get a reference to the destination view controller
let destinationVC:ViewControllerClass = segue.destinationViewController as! ViewControllerClass
//set properties on the destination view controller
destinationVC.name = viewName
//etc...
}
}
回答by Saqib Omer
For Swift 3.0
对于 Swift 3.0
final class Shared {
static let shared = Shared() //lazy init, and it only runs once
var stringValue : String!
var boolValue : Bool!
}
To set stringValue
设置 stringValue
Shared.shared.stringValue = "Hi there"
to get stringValue
要得到 stringValue
if let value = Shared.shared.stringValue {
print(value)
}
For Swift version below 3.0
对于 3.0 以下的 Swift 版本
You can pass data between views using singleton class. It is easy and efficient way. Here is my class ShareData.swift
您可以使用单例类在视图之间传递数据。这是一种简单有效的方法。这是我的班级 ShareData.swift
import Foundation
class ShareData {
class var sharedInstance: ShareData {
struct Static {
static var instance: ShareData?
static var token: dispatch_once_t = 0
}
dispatch_once(&Static.token) {
Static.instance = ShareData()
}
return Static.instance!
}
var someString : String! //Some String
var selectedTheme : AnyObject! //Some Object
var someBoolValue : Bool!
}
Now in my ViewControllerOne
I can set above variable.
现在ViewControllerOne
我可以在上面设置变量。
//Declare Class Variable
let shareData = ShareData.sharedInstance
override func viewDidLoad() {
self.shareData.someString ="Some String Value"
}
And in my ViewControllerTwo
I can access someString
as
而在我ViewControllerTwo
,我可以访问someString
如
let shareData = ShareData.sharedInstance
override func viewDidLoad() {
NSLog(self.sharedData.someString) // It will print Some String Value
}
回答by Ke Yang
Personally, I prefer ways as follow:
就个人而言,我更喜欢以下方式:
If you want to jump forward between two view controllers (from A to B), as -pushViewController:animated: in navigation, you can define a property of model for Controller B and expose it publicly, then set this property explicitly before jumping from Controller A, it's pretty straightforward;
In case you want to jump backward from Controller B to A, use Delegate+Protocol mode. Controller B drafts a public protocol and own a "delegate" property, any object who would like to be the delegate of Controller B shall comply and implement its protocol(optionally). then prior to the jumping-backward, Controller B makes its delegate perform certain action(s) listed in protocol, the data could be transferred in this way;
Under certain circumstance, you may want to transfer data from a Controller(or controllers) to other multiple Controllers, use Notification mechanism if this is the case.
如果你想在两个视图控制器之间跳转(从 A 到 B),如 -pushViewController:animated: 在导航中,你可以为控制器 B 定义一个模型的属性并公开它,然后在从控制器跳转之前显式设置这个属性A,这很简单;
如果您想从控制器 B 向后跳转到 A,请使用 Delegate+Protocol 模式。控制器 B 起草公共协议并拥有“委托”属性,任何想成为控制器 B 的委托的对象都应遵守并实施其协议(可选)。然后在向后跳转之前,控制器 B 使其委托执行协议中列出的某些操作,数据可以通过这种方式传输;
在某些情况下,您可能希望将数据从一个控制器(或多个控制器)传输到其他多个控制器,如果是这种情况,请使用通知机制。
Apple has detailed instructions about delegate mode, notification mode in official documentation, check them out in XCode, :)
Apple 在官方文档中有关于委托模式、通知模式的详细说明,请在 XCode 中查看,:)
回答by Byron Luo
Just need to follow 3 steps, let's assume you want to pass data from ViewControllerA to ViewControllerB:
只需执行 3 个步骤,假设您要将数据从 ViewControllerA 传递到 ViewControllerB:
- create a segue between ViewControllerA and ViewControllerB
- name the segue with a Identifier in the attributes inspector of it
- override the
prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!)
at ViewControllerA
- 在 ViewControllerA 和 ViewControllerB 之间创建一个 segue
- 在它的属性检查器中用标识符命名 segue
- 覆盖
prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!)
ViewControllerA
For step#3,:
对于步骤#3,:
- if you are not using swift 2.1, please follow @Scott Mielcarski 's answer at this question
for people who are using swift 2.1, or who get error"Cannot convert value of type 'UIViewController' to specified type 'your view Controller class name', After following @Scott Mielcarski 's answer at this question, Please use:
let destinationVC:ViewControllerClass = segue.destinationViewController as! ViewControllerClass
instead oflet destinationVC:ViewControllerClass = segue.destinationViewController
This is tested on Swift 2.1.1 and it works for me.
- 如果您没有使用 swift 2.1,请按照@Scott Mielcarski 在这个问题上的回答
对于使用swift 2.1或收到错误“无法将类型 'UIViewController' 的值转换为指定类型的'您的视图控制器类名' 的人,按照@Scott Mielcarski 对此问题的回答后,请使用:
let destinationVC:ViewControllerClass = segue.destinationViewController as! ViewControllerClass
而不是let destinationVC:ViewControllerClass = segue.destinationViewController
这是在 Swift 2.1.1 上测试过的,对我有用。