Empuje segue desde UITableViewCell a ViewController en Swift

Estoy encontrando problemas con mi UITableViewCells. Conecté mi UITableView a una API para poblar mis células.

Luego, he creado una function que indexPath.row el indexPath.row para identificar qué object JSON dentro de la matriz que debería enviarse al RestaurantViewController .

Enlace a mi proyecto Xcode para facilitar la debugging y la solución de problemas

Así es como mi pequeño fragment busca configurar los "clics de fila" en una variable global.

 func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { i = indexPath.row } 

Y aquí está mi function prepareForSegue() que debe conectar mi push-segue al RestaurantViewController .

 override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) { if segue.identifier == "toRestaurant"{ let navigationController = segue.destinationViewController as UINavigationController let vc = navigationController.topViewController as RestaurantViewController vc.data = currentResponse[i] as NSArray } } 

Y así es como he configurado mi segue desde UITableViewCell

Aquí está mi resultado, he intentado hacer clic en cada una de estas celdas, pero no voy a ser empujado a otro viewController … Tampoco recibo un error. ¿Qué está mal aquí?

Intenté soluciones que no funcionarán.

 override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) { if segue.identifier == "toRestaurant"{ let vc = segue.destinationViewController as RestaurantViewController //let vc = navigationController.topViewController as RestaurantViewController vc.data = currentResponse[i] as NSArray } } 

El problema es que no manejas tus datos correctamente. Si miras tu currentResponse Array, verás que contiene a NSDictionaries, pero en tu prepareForSegue intentas lanzar un NSDictionary a un NSArray, lo que hará que la aplicación se bloquee.

Cambie la variable de data en RestaurantViewController a un NSDictionary y cambie su prepareForSegue para pasar aa NSDictionary

 override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) { if let cell = sender as? UITableViewCell { let i = networkingditListTableView.indexPathForCell(cell)!.row if segue.identifier == "toRestaurant" { let vc = segue.destinationViewController as RestaurantViewController vc.data = currentResponse[i] as NSDictionary } } } 

Los siguientes pasos deben solucionar su problema. Si no es así, por favor hágamelo saber.

  1. Elimine su tableView(tableView, didSelectRowAtIndexPath:) .

  2. ¡Haga que los data en RestaurantViewController tengan el tipo NSDictionary!

  3. Determine la fila seleccionada en prepareForSegue :

     override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) { if let cell = sender as? UITableViewCell { let i = tableView.indexPathForCell(cell)!.row if segue.identifier == "toRestaurant" { let vc = segue.destinationViewController as RestaurantViewController vc.data = currentResponse[i] as NSDictionary } } } 

Enlace de Dropbox al directory stack3

  1. Estoy teniendo dificultades para entender por qué tu software es muy diferente a una estructura estándar de vista de tabla de 2 niveles. Así que codifiqué un breve ejemplo al que puede acceder desde este enlace. También he incluido el código de fonts a continuación.

  2. El progtwig imita lo que tienes (lo mejor que yo lo entendí). Table Controller 1 sigue al Table Controller 2 desde la celda tableview. No tuve problemas con segue-ing. Tenga en count que no tengo ni necesito boost el Libro de cuentos para iniciar la segue.

  3. He embedded ambos controlleres en los controlleres de navigation. Mi experiencia es que ahorra mucho esfuerzo para configurar la navigation.

  4. Alternativamente, podría tener el control arrastrado desde el primer símbolo de TableViewController en la parte superior de la pantalla al segundo controller y configurar el segue.

  5. Utilicé una variable global (selectedRow) aunque no es una práctica recomendable. Pero también usa fácilmente prepareForSegue para establecer una variable en RestaurantTableViewController (muestro un ejemplo)

    1. Finalmente, recomiendo verificar el Inspector de Conexiones (para la celda de vista de tabla en el primer controller) para confirmar que hay una segue para el segundo controller. Si controla y arrastra correctamente, debe aparecer un post de confirmación, así como una input en el Inspector de conexiones.

Lamentablemente no puedo get el código correctamente formateador

 import UIKit var selectedRow = -1 class TableViewController: UITableViewController { var firstArray = ["Item1","Item2","Item3","Item4"] override func viewDidLoad() { super.viewDidLoad() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } // MARK: - Table view data source override func numberOfSectionsInTableView(tableView: UITableView) -> Int { return 1 } override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return firstArray.count } let nameOfCell = "RestaurantCell" override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier(nameOfCell, forIndexPath: indexPath) as UITableViewCell cell.textLabel!.text = firstArray[indexPath.row] return cell } override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { selectedRow = indexPath.row } // MARK: - Navigation override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { let vc = segue.destinationViewController as RestaurantTableViewController // can write to variables in RestaurantTableViewController if requinetworking vc.someVariable = selectedRow } } import UIKit class RestaurantTableViewController: UITableViewController { var secondArray = ["Item 2.1", "Item 2.2", "Item 2.3", "Item 2.4"] var someVariable = -1 override func viewDidLoad() { super.viewDidLoad() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } // MARK: - Table view data source override func numberOfSectionsInTableView(tableView: UITableView) -> Int { return 1 } override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return secondArray.count } let nameOfCell = "RestaurantCell" override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier(nameOfCell, forIndexPath: indexPath) as UITableViewCell cell.textLabel!.text = secondArray[indexPath.row] if indexPath.row == selectedRow { cell.textLabel!.text = cell.textLabel!.text! + " SELECTED" } return cell } override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { selectedRow = indexPath.row } } 

Noté que en su captura de pantalla de su storyboard, el segue está conectando la primera celda de prototipo con el RestaurantViewController . Esta celda de prototipo se ve como el estilo de celda "Básico" con un accesorio de indicador de divulgación a la derecha. Pero mira la captura de pantalla de tu aplicación en ejecución. La tabla se rellena con celdas que parecen ser el estilo de celda "Subtítulos" sin un accesorio de indicador de divulgación a la derecha.

La razón por la que su segue nunca se dispara sin importar lo que haga es que segue solo está configurado para funcionar para una celda de prototipo específica, pero esa celda de prototipo nunca se usa cuando rellena la tabla. Lo que sea que esté haciendo en tableView:cellForRowAtIndexPath: no está utilizando la celda de prototipo que desee.

@Starscream tiene la idea correcta de eliminar la celda correcta con el identificador correcto y combinarla con el identificador de la celda prototipo en Interface Builder. El locking que obtienes incluso después de hacer eso podría deberse al problema anterior mencionado en los comentarios anteriores. Su segue en el guión gráfico está apuntando claramente a un UITableViewController . Su código en prepareForSegue:sender: debe let vc = segue.destinationViewController as RestaurantViewController , siempre que RestaurantViewController sea ​​una subclass de UITableViewController . Te bloqueará si intentas convertirlo en UINavigationController . Asegúrese también de que la class para el destino UITableViewController en el guión gráfico esté listda como RestaurantController en el panel del Inspector de identidad. Se bloqueará si su progtwig comstack pensando que el guión gráfico solo contiene un UITableViewController genérico allí.

Volviendo al problema original más, no sé cómo has implementado tableView:cellForRowAtIndexPath: que podría ser crucial. Quizás no sea tan simple. Tal vez planees manejar muchas celdas prototipo o generar celdas personalizadas en time de ejecución. En este caso, una forma de hacer que esto sea sencillo para usted es realizar de manera programática la segue cuando el usuario toca una celda. En lugar de utilizar una celda de prototipo específica, haga que el segue sea una connection que se origina desde el "Restauranger nära mig" UITableViewController va al RestaurantViewController . (Conéctese en el Generador de interfaces haciendo clic con el button secundario y arrastrando desde el ícono del Controlador de Vista de tabla en la parte superior de la primera hasta el cuerpo del segundo). Debe otorgarle a este segue un identificador en el panel Inspector de attributes para que esto sea útil. Digamos que es "toRestaurant" . Luego, al final de su tableView:didSelectRowAtIndexPath: método, coloque esta línea de código: self.performSegueWithIdentifier("toRestaurant", sender: self) . Ahora, no importa qué celda esté seleccionada en la tabla, esta segue siempre disparará por ti.

Intente crear celdas como esta en su método cellForRow :

 let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("MyTestCell", forIndexPath: indexPath) 

Estoy saliendo en un capricho aquí, ya que estoy tomando prepareForSegue() rápidas ahora, pero la forma en que lo hago en mi prepareForSegue() es algo como esto:

 override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) { if segue.identifier == "toRestaurant"{ let navigationController = segue.destinationViewController as UINavigationController let vc = navigationController.topViewController as RestaurantViewController //notice I changed [i] to [index!.row] vc.data = currentResponse[index!.row] as NSArray } } 

Lo que me parece a mí es que estás llamando a la variable i, que es como una especie de variable privada dentro de un método de tu class. Puedes hacer algo así como @Syed Tariq con la variable selectRow y configurarla por encima de tu class SomeController: UIViewController /*, maybe some more here? */ { class SomeController: UIViewController /*, maybe some more here? */ { y luego firma la variable dentro de tu

 override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { selectedRow = indexPath.row } 

método como el anterior, pero ambas forms deberían funcionar bastante bien.

Tuve el mismo problema y encontré la solución:

performSegueWithIdentifier ("toViewDetails", remitente: uno mismo)

 func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { var cellnumber = procMgr.processos[indexPath.row].numero println("You selected cell #\(indexPath.row)") println(cellnumber) performSegueWithIdentifier("toViewDetails", sender: self) } override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if segue.identifier == "toViewDetails" { let DestViewController : ViewDetails = segue.destinationViewController as! ViewDetails } } 

Es posible que deba get el índice de celda seleccionado de UItableview. A continuación, el código utilizó el índice de celda seleccionado (UItableview.indexPathForSelectedRow) para get un elemento correcto de la matriz.

 override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) { if segue.identifier == "seguaVisitCardDetial" { let viewController = segue.destinationViewController as! VCVisitCardDetial viewController.dataThisCard = self.listOfVisitCards[(tblCardList.indexPathForSelectedRow?.row)!] } }