ios 使用 Swift 使用 Segue 发送数据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26089152/
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 02:52:54  来源:igfitidea点击:

Sending data with Segue with Swift

iosswiftsegue

提问by Alex Catchpole

I have two view controllers and two views. In my first view, I set the variable 'currentUser' to false. I need to be able to set 'currentUser' to true in the second view controller.

我有两个视图控制器和两个视图。在我的第一个视图中,我将变量“currentUser”设置为 false。我需要能够在第二个视图控制器中将 'currentUser' 设置为 true。

When trying to reference 'currentUser' from the second view it's not picking it up as 'currentUser' is defined in the first view controller.

当尝试从第二个视图中引用 'currentUser' 时,它不会选择它,因为 'currentUser' 是在第一个视图控制器中定义的。

How do I carry across variables with segue?

如何使用 segue 传递变量?

回答by derdida

Set values from Any ViewController to a Second One using segues

使用 segue 将 Any ViewController 中的值设置为第二个

Like this:

像这样:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

    if(segue.identifier == "yourIdentifierInStoryboard") {

        let yourNextViewController = (segue.destinationViewController as yourNextViewControllerClass)
        yourNextViewController.value = yourValue

And in your yourNextViewController class.

并在 yourNextViewController 类中。

class yourNextViewControllerClass {

    var value:Int! // or whatever

You can call this also programmatically:

您也可以以编程方式调用它:

 self.performSegueWithIdentifier("yourIdentifierInStoryboard", sender: self)

Set values from your DestinationViewController back to your Primary (First) ViewController

将 DestinationViewController 中的值设置回主(第一个)ViewController

1.Implement a protocol, for example create a file called protocol.swift.

1.实现一个协议,例如创建一个名为 protocol.swift 的文件。

    protocol changeUserValueDelegate {
       func changeUser(toValue:Bool)
    }

2.set the delegate on your second View

2.在你的第二个视图上设置委托

    class yourNextViewControllerClass {

    var delegate:changeUserValueDelegate?

3.set the delegate on load (prepareForSegue)

3.在加载时设置委托 (prepareForSegue)

    if(segue.identifier == "yourIdentifierInStoryboard") {

        var yourNextViewController = (segue.destinationViewController as yourNextViewControllerClass)
        yourNextViewController.delegate = self

4.add Function to FirstViewController

4.为 FirstViewController 添加函数

    func changeUser(toValue:Bool) {
        self.currentUserValue = toValue
    }

5.call this function from your SecondViewController

5.从你的 SecondViewController 调用这个函数

     delegate?.changeUser(true)

6.Set the delegate in your FirstViewController

6.在你的 FirstViewController 中设置委托

    class FirstViewController: UIViewController, ChangeUserValueDelegate {

回答by Imanou Petit

The problem here is that your currentUservariable is of type Bool, which is a value type. So passing it from your first view controller to your second view controller will in fact create a new Boolinstance. What you need is to pass a reference from your first view controller to your second view controller (see Value and Reference Typesfor more details on value and reference with Swift).

这里的问题是你的currentUser变量是 type Bool,它是一个值类型。因此,将它从您的第一个视图控制器传递到您的第二个视图控制器实际上会创建一个新Bool实例。您需要将第一个视图控制器的引用传递到第二个视图控制器(有关值和引用的更多详细信息,请参阅值和引用类型)。

Thereby, according to your needs/preferences, you may choose one of the threefollowing examples.

因此,根据您的需要/偏好,您可以选择以下三个示例之一。



1. The boxing style

1.拳击风格

Here, we "box" our Boolinside a class and pass a reference of that class instance to the second view controller.

在这里,我们Bool在一个类中“装箱” ,并将该类实例的引用传递给第二个视图控制器。

1.1. Create a CurrentUserclass:

1.1. 创建一个CurrentUser类:

class CurrentUser {
    var someBooleanValue = true {
        didSet {
            print(someBooleanValue)
        }
    }
}

1.2. Create a UIViewControllersubclass for the first view controller:

1.2. UIViewController为第一个视图控制器创建一个子类:

import UIKit

class ViewController1: UIViewController {

    let currentUser = CurrentUser()

    override func viewDidLoad() {
        super.viewDidLoad()
        currentUser.someBooleanValue = false
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if let viewController2 = segue.destinationViewController as? ViewController2 {
            viewController2.currentUser = currentUser
        }
    }

}

1.3. Create a UIViewControllersubclass for the second view controller:

1.3. UIViewController为第二个视图控制器创建一个子类:

import UIKit

class ViewController2: UIViewController {

    var currentUser: CurrentUser?

    // Link this IBAction to a UIButton or a UIBarButtonItem in the Storyboard
    @IBAction func toggleBoolean(sender: AnyObject) {
        if let currentUser = currentUser {
          currentUser.someBooleanValue = !currentUser.someBooleanValue
        }
    }

}


2. The closure style

2. 闭合方式

Here, we get a weak reference of our first view controller in a closure and pass this closure to the second view controller.

在这里,我们在闭包中获得第一个视图控制器的弱引用,并将此闭包传递给第二个视图控制器。

2.1. Create a UIViewControllersubclass for the first view controller:

2.1. UIViewController为第一个视图控制器创建一个子类:

import UIKit

class ViewController1: UIViewController {

    var currentUser = true {
        didSet {
            print(currentUser)
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        currentUser = false
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if let viewController2 = segue.destinationViewController as? ViewController2 {
            let closureToPerform = { [weak self] in
                if let strongSelf = self {
                    strongSelf.currentUser = !strongSelf.currentUser
                }
            }
            viewController2.closureToPerform = closureToPerform
        }
    }

}

2.2. Create a UIViewControllersubclass for the second view controller:

2.2. UIViewController为第二个视图控制器创建一个子类:

import UIKit

class ViewController2: UIViewController {

    var closureToPerform: (() -> Void)?

    // Link this IBAction to a UIButton or a UIBarButtonItem in the Storyboard
    @IBAction func toggleBoolean(sender: AnyObject) {
        closureToPerform?()
    }

}


3. The protocol-delegate style

3. 协议委托风格

Here, we make our first view controller conform to some protocol and pass a weak reference of it to the second view controller.

在这里,我们让我们的第一个视图控制器符合某个协议,并将它的弱引用传递给第二个视图控制器。

3.1. Create a custom protocol:

3.1. 创建自定义协议:

protocol MyDelegate: class {
    func changeValue()
}

3.2. Create a UIViewControllersubclass for the first view controller and make it conform to the previous protocol:

3.2. UIViewController为第一个视图控制器创建一个子类并使其符合之前的协议:

import UIKit

class ViewController1: UIViewController, MyDelegate {

    var currentUser = true {
        didSet {
            print(currentUser)
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        currentUser = false
    }

    func changeValue() {
        currentUser = !currentUser
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if let viewController2 = segue.destinationViewController as? ViewController2 {
            viewController2.delegate = self
        }
    }

}

3.3. Create a UIViewControllersubclass for the second view controller:

3.3. UIViewController为第二个视图控制器创建一个子类:

import UIKit

class ViewController2: UIViewController {

    weak var delegate: MyDelegate?

    // Link this IBAction to a UIButton or a UIBarButtonItem in the Storyboard
    @IBAction func toggleBoolean(sender: AnyObject) {
        delegate?.changeValue()
    }

}

回答by ielyamani

Add an attribute currentUserSecondVCin the destination view controller, and use prepareForSegue

currentUserSecondVC在目标视图控制器中添加一个属性,并使用prepareForSegue

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "Name Of Your Segue" {
        var vc = segue.destinationViewController as NameOfTheSecondViewController
        vc.currentUserSecondVC = !currentUser //you can do whatever you want with it in the 2nd VC
    }
}

回答by Trombe

The function that should be defined as override is:

应该定义为覆盖的函数是:

open func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if (segue.identifier == "Segue Name Defined In Storyboard") {
        //set the property of the designated view controller with the value you need
    }
}

回答by Saranjith

Since you're using same variable across the two Viewcontrollers, namely currentUser (type Bool).

由于您在两个 Viewcontroller 中使用相同的变量,即 currentUser(类型 Bool)。

So its better to make it a global variable in both classes.

所以最好让它成为两个类中的全局变量。

When coming to global variable concept in swift.

在 swift 中谈到全局变量的概念时。

Everything by default in swift is public, and thus if you declare something like this:

默认情况下,swift 中的所有内容都是公开的,因此如果您声明如下内容:

class FirstViewController: UIViewController {

    var someVariable: Boll = YES

    init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }
}

You can access it and set values as long as you have an instance of it:

只要您有它的实例,就可以访问它并设置值:

var MySecondViewController: FirstViewController = FirstViewController(nibName: nil, bundle: nil)
var getThatValue = MySecondViewController.someVariable