2014-09-28 38 views
28

我有两个视图控制器和两个视图。 在我的第一个视图中,我将变量'currentUser'设置为false。 我需要能够在第二个视图控制器中将'currentUser'设置为true。Segue with Swift发送数据

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

如何通过segue传递变量?从任何视图控制器使用塞格斯

像这样

回答

49

设定值的第二个:

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

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

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

而在你yourNextViewController类。从DestinationViewController回

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

设定值的主(前)的ViewController

实现一个协议,例如:

class yourNextViewControllerClass { 

    var value:Int! // or whatever 

你也可以以编程方式调用此创建一个名为protocol.swift的文件。

protocol changeUserValueDelegate { 
     func changeUser(toValue:Bool) 
    } 

2.设置委托在你的第二个查看

class yourNextViewControllerClass { 

    var delegate:changeUserValueDelegate? 

设置委托负载(prepareForSegue)

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

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

4.附加功能到FirstViewController

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

5.呼叫从自己的SecondViewController

 delegate?.changeUser(true) 

6.此功能设置委托在FirstViewController

class FirstViewController: UIViewController, ChangeUserValueDelegate { 
+0

我不能使用函数,我知道我需要在'if'语句中做这个。对不起,没有更清楚。 – AlexCatch 2014-09-28 20:23:49

+0

使用这2种方法,您可以将数据从第一个视图控制器发送到第二个视图控制器,并从第二个视图控制器发送到第一个视图控制器。在“if”语句中调用它不应该是个问题。 – derdida 2014-09-28 20:30:45

+0

我试过第一种方法,我不能在if语句中使用覆盖函数,在第二个视图控制器中找不到该变量。 – AlexCatch 2014-09-28 20:41:31

1

在目标视图控制器添加属性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 
    } 
} 
12

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

因此,根据您的需求/喜好,您可以选择其中一个三个以下示例。


1.拳式

在这里,我们的“盒子”我们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.关闭风格

在这里,我们得到了我们的第一个视图控制器在一个封闭弱引用和这个封闭传递给第二个视图控制器。

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.协议的代表风格

在这里,我们做我们的第一个视图控制器符合一些协议,并通过一个弱引用它到第二个视图控制器。

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() 
    } 

} 
+1

伟大的答案与伟大的代码片段。与derdida的答案相比,这提供了两种处理发送数据的方法。 – 2017-02-07 15:57:37

0

应该被定义为超控的功能是:

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 
    } 
} 
0

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

所以它更好地使它成为两个类中的全局变量。

在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