ios - performsegue - segue swift 4
EnvĂo de datos con Segue con Swift (5)
Tengo dos controladores de vista y dos vistas. En mi primera vista, configuré la variable ''currentUser'' en falso. Necesito poder establecer ''currentUser'' en verdadero en el segundo controlador de vista.
Cuando se trata de hacer referencia a ''currentUser'' desde la segunda vista, no se detecta como ''currentUser'' se define en el primer controlador de vista.
¿Cómo transfiero variables con segue?
Agregue un atributo
currentUserSecondVC
en el controlador de vista de destino y use
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
}
}
Dado que está utilizando la misma variable en los dos Viewcontrollers, es decir, currentUser (tipo Bool).
Por lo tanto, es mejor convertirlo en una variable global en ambas clases.
Al llegar al concepto de variable global en forma rápida.
Todo por defecto en swift es público, y por lo tanto si declaras algo como esto:
class FirstViewController: UIViewController {
var someVariable: Boll = YES
init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
}
Puede acceder a él y establecer valores siempre que tenga una instancia de él:
var MySecondViewController: FirstViewController = FirstViewController(nibName: nil, bundle: nil)
var getThatValue = MySecondViewController.someVariable
El problema aquí es que su variable
currentUser
es de tipo
Bool
, que es un tipo de valor.
Por lo tanto, pasarlo de su primer controlador de vista a su segundo controlador de vista creará una nueva instancia de
Bool
.
Lo que necesita es pasar una referencia desde su primer controlador de vista a su segundo controlador de vista (consulte
Tipos de valores y referencias
para obtener más detalles sobre el valor y la referencia con Swift).
Por lo tanto, de acuerdo con sus necesidades / preferencias, puede elegir uno de los tres ejemplos siguientes.
1. El estilo de boxeo
Aquí, "encajonamos" nuestro
Bool
dentro de una clase y pasamos una referencia de esa instancia de clase al segundo controlador de vista.
1.1.
Crear una clase
CurrentUser
:
class CurrentUser {
var someBooleanValue = true {
didSet {
print(someBooleanValue)
}
}
}
1.2.
Cree una subclase
UIViewController
para el primer controlador de vista:
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.
Cree una subclase
UIViewController
para el segundo controlador de vista:
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. El estilo de cierre
Aquí, obtenemos una referencia débil de nuestro primer controlador de vista en un cierre y pasamos este cierre al segundo controlador de vista.
2.1.
Cree una subclase
UIViewController
para el primer controlador de vista:
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.
Cree una subclase
UIViewController
para el segundo controlador de vista:
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. El estilo de delegado de protocolo
Aquí, hacemos que nuestro primer controlador de vista se ajuste a algún protocolo y pase una referencia débil del mismo al segundo controlador de vista.
3.1. Crea un protocolo personalizado:
protocol MyDelegate: class {
func changeValue()
}
3.2.
Cree una subclase
UIViewController
para el primer controlador de vista y haga que se ajuste al protocolo anterior:
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.
Cree una subclase
UIViewController
para el segundo controlador de vista:
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()
}
}
La función que debe definirse como anulación es:
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
}
}
Establecer valores de Any ViewController a un segundo usando segues
Me gusta esto:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "yourIdentifierInStoryboard") {
let yourNextViewController = (segue.destinationViewController as yourNextViewControllerClass)
yourNextViewController.value = yourValue
Y en su clase yourNextViewController.
class yourNextViewControllerClass {
var value:Int! // or whatever
También puede llamar a esto mediante programación:
self.performSegueWithIdentifier("yourIdentifierInStoryboard", sender: self)
Establezca valores desde su DestinationViewController de nuevo a su principal (primer) ViewController
1. Implemente un protocolo, por ejemplo, cree un archivo llamado protocol.swift.
protocol changeUserValueDelegate {
func changeUser(toValue:Bool)
}
2. configure el delegado en su segunda Vista
class yourNextViewControllerClass {
var delegate:changeUserValueDelegate?
3. establecer el delegado en carga (prepareForSegue)
if(segue.identifier == "yourIdentifierInStoryboard") {
var yourNextViewController = (segue.destinationViewController as yourNextViewControllerClass)
yourNextViewController.delegate = self
4. agregar Función a FirstViewController
func changeUser(toValue:Bool) {
self.currentUserValue = toValue
}
5. llame a esta función desde su SecondViewController
delegate?.changeUser(true)
6. Configure el delegado en su FirstViewController
class FirstViewController: UIViewController, ChangeUserValueDelegate {