Devuelve múltiples variables al completar el Controlador de Vista.
¿Cómo puedo pasar múltiples variables de vuelta en la finalización del controlador de vista sin usar estructuras o clases?
Aquí está mi código que funciona:
class TimerViewController: UIViewController {
// CÓDIGO IRRELEVANTE ELIMINADO
@IBAction func editTimerButtonPressed(_ sender: UIButton) {
self.performSegue(withIdentifier: "goToEditTimer", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToEditTimer" {
let destinationVC = segue.destination as! EditTimerViewController
destinationVC.duration = Int(myTimer.totalTime)
destinationVC.timerName = myTimer.timerName
destinationVC.completion = { [weak self] duration, name in
DispatchQueue.main.async {
self?.myTimer.totalTime = Double(duration!)
self?.timerLabel.text = name!
self?.timer.invalidate()
}
}
}
}
}
class EditTimerViewController: UIViewController, UITextFieldDelegate {
var duration: Int? // la duración del temporizador se pasa desde Timer
var timerName: String?
public var completion: ((Int?, String?) -> Void)?
// CÓDIGO IRRELEVANTE ELIMINADO
@IBAction func savePressed(_ sender: UIButton) {
timerName = timerNameField.text
completion?(duration, timerName)
self.dismiss(animated: true, completion: nil)
}
}
Pero ahora quiero pasar los cambios realizados no solo a la duration
, sino también al timerName
.
ACTUALIZACIÓN
Siguiendo el consejo de @koen, intenté poner ambas variables en una tupla, pero obtuve un error que no puedo entender.
Aquí declaro timerData
como una tupla de (Int?, String?)
pero obtengo un error que el tipo de argumento esperado es Int?
:
class EditTimerViewController: UIViewController, UITextFieldDelegate {
var duration: Int? // la duración del temporizador se pasa desde Timer
var timerName: String?
public var completion: ((Int?, String?) -> Void)?
// CÓDIGO IRRELEVANTE ELIMINADO
@IBAction func savePressed(_ sender: UIButton) {
timerName = timerNameField.text
let timerData = (duration: duration, name: timerName)
completion?(timerData) // ERROR Cannot convert value of type '(duration: Int?, name: String?)' to expected argument type 'Int?'
self.dismiss(animated: true, completion: nil)
}
}
Pero estoy recibiendo errores para las siguientes cadenas:
self?.myTimer.totalTime = Double(timerData[0]!)
self?.timerLabel.text = String(timerData[1]!)
Pero no lo estoy declarando en el VC principal:
class TimerViewController: UIViewController {
// CÓDIGO IRRELEVANTE ELIMINADO
// timerData no fue declarado
@IBAction func editTimerButtonPressed(_ sender: UIButton) {
self.performSegue(withIdentifier: "goToEditTimer", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToEditTimer" {
let destinationVC = segue.destination as! EditTimerViewController
destinationVC.duration = Int(myTimer.totalTime)
destinationVC.timerName = myTimer.timerName
let timerData = (duration: destinationVC.duration, name: destinationVC.timerName)
destinationVC.completion = { [weak self] timerData in // si verifico timerData, se describe como Declaración let timerData: Int? Declarado en TimerViewController.swift
DispatchQueue.main.async {
self?.myTimer.totalTime = Double(timerData.duration!) // ERROR Argument passed to call that takes no arguments + ERROR Value of type 'Int?' has no member 'duration'
self?.timerLabel.text = timerData.name // ERROR Argument passed to call that takes no arguments + ERROR Value of type 'Int?' has no member 'duration'
self?.timer.invalidate()
}
}
}
}
}
davy.ai
Para devolver varias variables en la finalización del Controlador de Vista sin usar structs o clases, se pueden utilizar tuplas. Las tuplas permiten agrupar varios valores de cualquier tipo en un solo valor compuesto.
Para devolver tanto la
duración
como elnombre del temporizador
desdeEditTimerViewController
aTimerViewController
, se puede definir una tupla con estos valores:Luego, pase esta tupla al cierre de
completion
enEditTimerViewController
:En
TimerViewController
, puede recibir esta tupla y acceder a sus valores:Asegúrese de actualizar el tipo de
completion
enEditTimerViewController
para aceptar una tupla:Tenga en cuenta que si recibe errores al intentar acceder a los valores de la tupla, asegúrese de acceder correctamente a las propiedades de la tupla por su nombre, según se define al crear la tupla.