J'ai deux contrôleurs de vue et deux vues . Dans ma première vue, j'ai défini la variable "currentUser" sur false .
Lorsque vous essayez de référencer 'currentUser' à partir de la deuxième vue, il ne la détecte pas car 'currentUser' est défini dans le premier contrôleur de vue.
Comment puis-je transporter des variables avec segue?
Définissez les valeurs de Any ViewController sur un second à l'aide de segues
Comme ça:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "yourIdentifierInStoryboard") {
let yourNextViewController = (segue.destinationViewController as yourNextViewControllerClass)
yourNextViewController.value = yourValue
Et dans votre classe yourNextViewController.
class yourNextViewControllerClass {
var value:Int! // or whatever
Vous pouvez appeler cela aussi par programme:
self.performSegueWithIdentifier("yourIdentifierInStoryboard", sender: self)
Définissez les valeurs de votre DestinationViewController dans votre ViewController (premier) principal
1. Implémentez un protocole, par exemple créez un fichier appelé protocole.Swift.
protocol changeUserValueDelegate {
func changeUser(toValue:Bool)
}
2. définir le délégué sur votre deuxième vue
class yourNextViewControllerClass {
var delegate:changeUserValueDelegate?
3. définir le délégué en charge (prepareForSegue)
if(segue.identifier == "yourIdentifierInStoryboard") {
var yourNextViewController = (segue.destinationViewController as yourNextViewControllerClass)
yourNextViewController.delegate = self
4. ajouter une fonction à FirstViewController
func changeUser(toValue:Bool) {
self.currentUserValue = toValue
}
5. appelez cette fonction à partir de votre SecondViewController
delegate?.changeUser(true)
6. Définir le délégué dans votre FirstViewController
class FirstViewController: UIViewController, ChangeUserValueDelegate {
Le problème ici est que votre variable currentUser
est de type Bool
, qui est un type valeur. Donc, le passer de votre premier contrôleur de vue à votre second contrôleur de vue créera en fait une nouvelle instance Bool
. Ce qu'il vous faut, c'est transmettre une référence de votre premier contrôleur de vue à votre second contrôleur de vue (voir Types de valeur et de référence pour plus de détails sur la valeur et la référence avec Swift).
Ainsi, selon vos besoins/préférences, vous pouvez choisir l’un des trois exemples suivants.
Ici, nous "boxons" notre Bool
à l'intérieur d'une classe et passons une référence de cette instance de classe au second contrôleur de vue.
1.1. Créez une classe CurrentUser
:
class CurrentUser {
var someBooleanValue = true {
didSet {
print(someBooleanValue)
}
}
}
1.2. Créez une sous-classe UIViewController
pour le premier contrôleur de vue:
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. Créez une sous-classe UIViewController
pour le second contrôleur de vue:
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
}
}
}
Ici, nous obtenons une référence faible de notre premier contrôleur de vue dans une fermeture et passons cette fermeture au second contrôleur de vue.
2.1. Créez une sous-classe UIViewController
pour le premier contrôleur de vue:
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. Créez une sous-classe UIViewController
pour le second contrôleur de vue:
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?()
}
}
Ici, nous faisons en sorte que notre premier contrôleur de vue se conforme à un protocole et en transmettons une faible référence au second contrôleur de vue.
3.1. Créez un protocole personnalisé:
protocol MyDelegate: class {
func changeValue()
}
3.2. Créez une sous-classe UIViewController
pour le premier contrôleur de vue et conformez-le au protocole précédent:
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. Créez une sous-classe UIViewController
pour le second contrôleur de vue:
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()
}
}
Ajoutez un attribut currentUserSecondVC
dans le contrôleur de vue de destination et utilisez 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
}
}
La fonction qui devrait être définie comme remplacement est la suivante:
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
}
}
Puisque vous utilisez la même variable sur les deux Viewcontrollers, à savoir currentUser (type Bool).
Il vaut donc mieux en faire une variable globale dans les deux classes.
En venant au concept de variable globale dans Swift.
Tout par défaut dans Swift est public, et donc si vous déclarez quelque chose comme ceci:
class FirstViewController: UIViewController {
var someVariable: Boll = YES
init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
}
Vous pouvez y accéder et définir des valeurs tant que vous en avez une instance:
var MySecondViewController: FirstViewController = FirstViewController(nibName: nil, bundle: nil)
var getThatValue = MySecondViewController.someVariable