2014-07-04 10 views
7

Sto passando i dati da un controller di visualizzazione tabella a una vista di dettaglio. Ho provato ad utilizzare indexPath.row direttamente nel mio metodo prepareForSegue, tuttavia si visualizza un errore diSegue non viene selezionato il numero di riga

uso di identificatore irrisolto 'indexPath'

Così, dopo la ricerca sul web, ho impostato la variabile indexOfSelectedPerson che è assegnato il valore di indexPath.row. Il problema quando eseguo l'app nel simulatore è che prepareForSegue sta ottenendo il valore iniziale di indexOfSelectedPerson (0), quindi ottiene il valore della riga selezionata solo dopo averlo fatto clic. Quindi, quando premo il pulsante Indietro nel simulatore e seleziono una riga diversa, la vista dettagliata mostra le informazioni della riga che ho selezionato la volta precedente.

import UIKit 

class MasterTableViewController: UITableViewController { 

    var people = [] 
    var indexOfSelectedPerson = 0 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     people = ["Bob", "Doug", "Jill"] 
    } 

    override func numberOfSectionsInTableView(tableView: UITableView?) -> Int { 
     return 1 
    } 

    override func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -> Int { 
     return people.count 
    } 

    override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! { 

     let cell = tableView!.dequeueReusableCellWithIdentifier("personCell", forIndexPath: indexPath) as UITableViewCell 

     cell.text = "\(people[indexPath.row])" 

     return cell 
    } 

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


    override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) { 

     if let mySegue = segue.identifier { 

      if mySegue == "personDetails" { 

       let detailsVC: DetailTableViewController = segue.destinationViewController as DetailTableViewController 

       detailsVC.selectedPersonName = "\(people[indexOfSelectedPerson])" 
      } 
     } 
    } 
} 

Così, selezionando Doug quando l'app inizia prima nel simulatore visualizza i dettagli per Bob perché indexPathOfSelectedPerson è 0. Premendo il pulsante Indietro e quindi selezionando Jill visualizza i dettagli per Doug perché indexPathOfSelectedPerson divenne 1 quando ho cliccato su Doug la volta precedente. Immagino che il problema derivi dall'ordine in cui vengono chiamati i metodi.

risposta

16

Il modo migliore per fare questo genere di cose è non utilizzare il delegato.

override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) { 
    let selectedIndex = self.tableView.indexPathForCell(sender as UITableViewCell) 
    // Do your stuff with selectedIndex.row as the index 
} 
+0

tuo line Aggiunto ha dato un errore in Xcode per quanto riguarda downcasting ANYOBJECT e ha suggerito di cambiare la linea: lasciare selectedIndex = self.tableView.indexPathForCell (mittente come UITableViewCell). Quello ha riparato l'errore. Ho cambiato indexOfSelectedPerson su selectedIndex.row come hai detto e tutto funziona. Grazie. – Shades

+0

Buona cattura, ho modificato la risposta. – Jack

+2

Proprio quello che stavo cercando. In Xcode 7 (Swift 2.2), è necessario forzare il cast del mittente a un 'UITableViewCell' in questo modo: ' self.tableView.indexPathForCell (sender as! UITableViewCell) ' –

-1
//In didSelectRowAtIndexPath, you use this code: 

func tableView(tvMain: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 

     self.performSegueWithIdentifier("yourSegueName", sender: nil) 

    } 

//And prepareForSegue to get IndexPath and send your value 

override func prepareForSegue(segue: UIStoryboardSegue, 
     sender: AnyObject!){ 

      let indexPath : NSIndexPath = self.yourTableView.indexPathForSelectedRow()! 
      //make sure that the segue is going to secondViewController 
      let detailsVC = segue.destinationViewController as DetailTableViewController 
      detailsVC.selectedPersonName = "\(people[indexPath.row])" 

    } 
1

Swift 3 aggiornamento:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    let selectedIndex = tableView.indexPath(for: sender as! UITableViewCell)! 
    // Do your actual preparing here... 
}