example - Enviar datos de TableView a DetailView Swift
list view swift 4 (4)
Estoy tratando de hacer quizás una de las cosas más simples y confusas para mí hasta ahora. Quiero desarrollar mi propia aplicación, y para hacerlo necesito poder pasar alguna información dependiendo de qué fila haga clic el usuario (es Swift lenguage)
Tenemos un RootViewController (vista de tabla) y DetailViewController (con 1 etiqueta y 1 imagen)
(nuestra vista)
Aquí está el código:
@IBOutlet weak var tableView: UITableView!
var vehicleData : [String] = ["Ferrari 458" , "Lamborghini Murcielago" , "Bugatti Veyron", "Mercedes Benz Biome"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var nib = UINib(nibName: "TableViewCell", bundle: nil)
tableView.registerNib(nib, forCellReuseIdentifier: "cell")
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return vehicleData.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:TableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as TableViewCell
cell.lblCarName.text = vehicleData[indexPath.row]
cell.imgCar.image = UIImage(named: vehicleData[indexPath.row])
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
performSegueWithIdentifier("DetailView", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "DetailView") {
var vc = segue.destinationViewController as DetailViewController
}
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 100
}
Clase TableViewCell personalizada (tiene un archivo xib con celda)
class TableViewCell: UITableViewCell {
@IBOutlet weak var lblCarName: UILabel!
@IBOutlet weak var imgCar: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
class DetailViewController: UIViewController {
@IBOutlet weak var lblDetail: UILabel!
@IBOutlet weak var imgDetail: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
}
La pregunta es:
si el usuario hace clic en Ferrari 458, el lblDetail en DetailViewController mostrará: Ferrari 458 es un supercoche que puede alcanzar 325 km / h ...... (lo que queramos) e imgDetail podría mostrar una imagen (lo que sea queremos) del auto
Si el usuario hace clic en Bugatti Veyron ahora el lblDetail nos muestra: Bugatti Veyron es una máquina perfecta y súper deportiva. Es uno de los autos más rápidos del mundo ...
imgDetail muéstranos una imagen de este auto
Lo mismo con todos los autos, dependiendo de la fila en la que hemos hecho clic
Sé que el trabajo se basa en la función prepareForSegue en el primer controlador de vista, pero estaba intentando muchas formas diferentes de hacerlo posible y todo funciona bien
¿Cómo podemos hacer esto?
Aquí está el ejemplo para ti:
var valueToPass:String!
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
println("You selected cell #/(indexPath.row)!")
// Get Cell Label
let indexPath = tableView.indexPathForSelectedRow!
let currentCell = tableView.cellForRowAtIndexPath(indexPath)! as UITableViewCell
valueToPass = currentCell.textLabel.text
performSegueWithIdentifier("yourSegueIdentifer", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){
if (segue.identifier == "yourSegueIdentifer") {
// initialize new view controller and cast it as your view controller
var viewController = segue.destinationViewController as AnotherViewController
// your new view controller should have property that will store passed value
viewController.passedValue = valueToPass
}
}
Pero no olvides crear una variable
passedValue
en
DetailViewController
.
Este es solo un ejemplo de pasar datos de un viewController a otro y puede pasar datos con este ejemplo según lo necesite.
Y para más información consulte estos enlaces.
Pasar valores entre ViewControllers en función de la selección de lista en Swift
¿Usó didSelectRowAtIndexPath o el método prepareForSegue para UITableView?
Swift: pase la etiqueta UITableViewCell al nuevo ViewController
https://teamtreehouse.com/forum/help-swift-segue-with-variables-is-not-working
Puede ser que esto te ayude.
Swift 3.0
var valueToPass:String!
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("You selected cell #/(indexPath.row)!")
// Get Cell Label
let indexPath = tableView.indexPathForSelectedRow!
let currentCell = tableView.cellForRow(at: indexPath)! as UITableViewCell
valueToPass = currentCell.textLabel?.text
performSegue(withIdentifier: "yourSegueIdentifer", sender: self)
}
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){
if (segue.identifier == "yourSegueIdentifer") {
// initialize new view controller and cast it as your view controller
var viewController = segue.destination as! AnotherViewController
// your new view controller should have property that will store passed value
viewController.passedValue = valueToPass
}
}
Es simple, estoy agregando una declaración a la respuesta anterior. Para obtener el nombre del automóvil seleccionado en la etiqueta de vista detallada,
lblDetail.text = passValue
puede agregar este código de línea en la función viewDidLoad () de su vista detallada. passValue contiene el nombre del automóvil que seleccionó el usuario (asignar en prepareForSegue) y luego puede asignarlo a su etiqueta de vista detallada.
¡¡Espero eso ayude!!
Esta puede ser otra solución, sin mucho código en el método didSelectRowAtIndexPath. Tenga en cuenta que si bien puede parecer más limpio, y no necesitamos una variable extra valueToPass, puede que no sea una mejor práctica, porque el argumento del remitente dentro del método performSegue se supone que es el objeto real que inició el segue (o nulo).
// MARK: UITableViewDelegate methods
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
performSegue(withIdentifier: "goToSecondVC", sender: indexPath)
}
// MARK: UIViewController methods
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToSecondVC" {
if segue.destination.isKind(of: CarDetailsController.self) {
let secondVC = segue.destination as! CarDetailsController
let indexPath = sender as! IndexPath
secondVC.passedValue = carsArray[indexPath.row]
}
}
}
Si arrastra un segue de la celda prototipo (en el Creador de interfaces) a su próximo Controlador de vista y establece su identificador de segue en "Su identificador de Segue", también puede hacerlo con este acceso directo:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "Your Segue Identifier" {
let cell = sender as! YourCustomCell
let vc = segue.destination as! PushedViewController
vc.valueToPass = cell.textLabel?.text // or custom label
}
}
Y tampoco necesita el
performSegueWithIdentifier()
en
didSelectRowAtIndexPath()
, ni este método de Vista de tabla.
En
PushedViewController.swift
(el siguiente controlador de vista):
var valueToPass: String!
override func viewDidLoad() {
super.viewDidLoad()
yourLabel.text = valueToPass
}
Es importante establecer el valor de la etiqueta
después de que
se inicialice desde el Guión gráfico.
Eso significa que no puede establecer la etiqueta en el
prepareForSegue()
View Controller anterior directamente, por lo tanto, debe pasarlo con
valueToPass
.