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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 01:46:45  来源:igfitidea点击:

How do you pass data between view controllers in Swift?

iosswift

提问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 ViewControllerOneI can set above variable.

现在ViewControllerOne我可以在上面设置变量。

//Declare Class Variable

let shareData = ShareData.sharedInstance

override func viewDidLoad() {
    self.shareData.someString ="Some String Value"
}

And in my ViewControllerTwoI can access someStringas

而在我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:

  1. create a segue between ViewControllerA and ViewControllerB
  2. name the segue with a Identifier in the attributes inspector of it
  3. override the prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!)at ViewControllerA
  1. 在 ViewControllerA 和 ViewControllerB 之间创建一个 segue
  2. 在它的属性检查器中用标识符命名 segue
  3. 覆盖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! ViewControllerClassinstead 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 上测试过的,对我有用。