【发布时间】:2014-11-23 05:04:43
【问题描述】:
我有两个视图控制器和两个视图。 在我的第一个视图中,我将变量“currentUser”设置为 false。 我需要能够在第二个视图控制器中将 'currentUser' 设置为 true。
当尝试从第二个视图中引用“currentUser”时,它不会将其拾取,因为“currentUser”是在第一个视图控制器中定义的。
如何使用 segue 跨变量?
【问题讨论】:
我有两个视图控制器和两个视图。 在我的第一个视图中,我将变量“currentUser”设置为 false。 我需要能够在第二个视图控制器中将 'currentUser' 设置为 true。
当尝试从第二个视图中引用“currentUser”时,它不会将其拾取,因为“currentUser”是在第一个视图控制器中定义的。
如何使用 segue 跨变量?
【问题讨论】:
使用 segues 将任何 ViewController 中的值设置为第二个
像这样:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "yourIdentifierInStoryboard") {
let yourNextViewController = (segue.destinationViewController as yourNextViewControllerClass)
yourNextViewController.value = yourValue
在你的 NextViewController 类中。
class yourNextViewControllerClass {
var value:Int! // or whatever
您也可以通过编程方式调用它:
self.performSegueWithIdentifier("yourIdentifierInStoryboard", sender: self)
将 DestinationViewController 中的值设置回主(第一个)ViewController
1.实现一个协议,例如创建一个名为protocol.swift的文件。
protocol changeUserValueDelegate {
func changeUser(toValue:Bool)
}
2.在您的第二个视图上设置代理
class yourNextViewControllerClass {
var delegate:changeUserValueDelegate?
3.设置代理加载(prepareForSegue)
if(segue.identifier == "yourIdentifierInStoryboard") {
var yourNextViewController = (segue.destinationViewController as yourNextViewControllerClass)
yourNextViewController.delegate = self
4.向FirstViewController添加Function
func changeUser(toValue:Bool) {
self.currentUserValue = toValue
}
5.从您的 SecondViewController 调用此函数
delegate?.changeUser(true)
6. 在您的 FirstViewController 中设置委托
class FirstViewController: UIViewController, ChangeUserValueDelegate {
【讨论】:
这里的问题是您的currentUser 变量是Bool 类型,这是一个值类型。因此,将它从您的第一个视图控制器传递到您的第二个视图控制器实际上会创建一个新的 Bool 实例。您需要将第一个视图控制器的引用传递给第二个视图控制器(有关 Swift 值和引用的更多详细信息,请参阅Value and Reference Types)。
因此,根据您的需要/偏好,您可以选择以下三个示例之一。
在这里,我们将Bool“装箱”在一个类中,并将该类实例的引用传递给第二个视图控制器。
1.1.创建一个CurrentUser 类:
class CurrentUser {
var someBooleanValue = true {
didSet {
print(someBooleanValue)
}
}
}
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。为第二个视图控制器创建一个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.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.为第二个视图控制器创建一个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.1.创建自定义协议:
protocol MyDelegate: class {
func changeValue()
}
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.为第二个视图控制器创建一个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()
}
}
【讨论】:
在目标视图控制器中添加属性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
}
}
【讨论】:
应该定义为override的函数是:
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
}
}
【讨论】:
由于您在两个 Viewcontrollers 中使用相同的变量,即 currentUser(类型 Bool)。
因此最好将其设为两个类中的全局变量。
当谈到 swift 中的全局变量概念时。
默认情况下,swift 中的所有内容都是公开的,因此如果您声明如下内容:
class FirstViewController: UIViewController {
var someVariable: Boll = YES
init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
}
只要您有它的实例,您就可以访问它并设置值:
var MySecondViewController: FirstViewController = FirstViewController(nibName: nil, bundle: nil)
var getThatValue = MySecondViewController.someVariable
【讨论】: