2016-03-19 3 views
-1

Dans iOS/Swift, j'ai créé un UITableView "client" indexé basé sur la propriété clientName dans ma classe Client. J'ai créé un dictionnaire avec A à Z comme les sections. La tableview indexée fonctionne très bien. Cependant, j'essaie de trouver un moyen de déterminer quelle ligne est dans le tableau source d'origine, lorsque l'utilisateur sélectionne une ligne. Je pensais construire un type de tableau de références croisées, sauf que le dictionnaire finit par être trié pour correspondre aux sections, donc je ne sais pas quel combo de section/ligne correspond à l'entrée de tableau d'origine. Existe-t-il une approche commune pour gérer ce problème?Vous voulez indexview tableview avec référence retour au tableau source

Pour tenter de clarifier ...

class Client { 
    var clientId    : Int! 
    var firstName   : String! 
    var lastName    : String! 
    var email    : String! 
    var phone    : String! 
    ... 

    init() { 

    } 
} 

var clients: [Client] = [] 

// clients array loaded from web service 
... 

// Create dictionary to be source for indexed tableview 
func createClientDict() { 
    clientDict   = [String: [String]]() 
    clientSectionTitles = [String]() 

    var clientNames:[String] = [] 
    for i in 0..<clients.count { 
     let client = clients[i] 

     let clientName = "\(client.lastName), \(client.firstName)" 
     clientNames.append(clientName) 
    } 

    for name in clientNames { 
     var client: Client = Client() 

     // Get the first letter of the name and build the dictionary 
     let clientKey = name.substringToIndex(name.startIndex.advancedBy(1)) 
     if var clientValues = clientDict[clientKey] { 
      clientValues.append(name) 
      clientDict[clientKey] = clientValues 
     } else { 
      clientDict[clientKey] = [name] 
     } 
    } 

    // Get the section titles from the dictionary's keys and sort them in ascending order 
    clientSectionTitles = [String](clientDict.keys) 
    clientSectionTitles = clientSectionTitles.sort { $0 < $1 } 
} 

Maintenant, lorsque l'utilisateur tape une ligne dans la tableview, je peux obtenir la section et la ligne (indexPath). Cependant, comment puis-je déterminer quelle ligne dans le tableau de clients est la correspondance, en supposant qu'il pourrait y avoir des noms en double? Existe-t-il un moyen de créer une référence croisée de la section/ligne indexée mappée à la ligne dans le tableau source à la volée? J'allais essayer de le faire en construisant le dictionnaire, sauf que le dictionnaire est trié après, donc rien ne correspondrait. Peut-être devrais-je inclure le numéro de ligne source dans/avec le dictionnaire?

Voici le code tableview:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! ClientCell 

    let clientKey = clientSectionTitles[indexPath.section] 
    if let clientValues = clientDict[clientKey] { 
     cell.clientName.text = clientValues[indexPath.row] 
    } 

    return cell 
} 

func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
    return clientSectionTitles.count 
} 

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    let clientKey = clientSectionTitles[section] 
    if let clientValues = clientDict[clientKey] { 
     return clientValues.count 
    } 

    return 0 
} 

func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 
    return clientSectionTitles[section] 
} 

func sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? { 
    return clientIndexTitles 
} 

func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int { 

    guard let index = clientSectionTitles.indexOf(title) else { 
     return -1 
    } 

    return index 
} 

func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 
    return 20 
} 

func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) { 
    let headerView = view as! UITableViewHeaderFooterView 

    headerView.contentView.backgroundColor = UIColor (red: 0.0, green: 0.3294, blue: 0.6392, alpha: 1.0) 
    headerView.textLabel?.textColor = UIColor.greenColor() 
    headerView.textLabel?.font = UIFont(name: "Noteworthy-bold", size: 15.0) 
} 

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
    selectedIndex = indexPath 

    // In the following prepare for segue, I need to somehow use the selected indexpath to find the correct entry 
    // in the clients array and pass it along. 

    performSegueWithIdentifier("clientDetailSegue", sender: self) 
} 
+0

Cette question [a besoin d'aide] (http://importblogkit.com/2016/03/how-to-ask- a-good-stack-overflow-question /). – nhgrif

+0

Où est le code de votre vue de table? Aussi ... cette classe 'Client' est un crash qui attend de se produire ...'! ' – nhgrif

+0

J'ai modifié pour ajouter du code de vue de table. J'ai essayé de déterminer lequel est le plus effrayant dans mes définitions de classe. Avoir toutes les propriétés optionnelles a aussi ses propres problèmes, mais peut-être pas aussi mauvais. – Lastmboy

Répondre

0

I figured it out. Je n'ai pas réalisé (jusqu'à ce que je l'ai récemment essayé) que vous puissiez imbriquer un tableau de n'importe quelle classe dans un dictionnaire. Quand j'ai changé mon dictionnaire pour que mon tableau de clients soit imbriqué, tout a été résolu. J'ai changé ma fonction comme indiqué ci-dessous.

func createClientDict() { 
    // Declared for view controller. Re-initialized here. 
    clientDict   = [String: [Client]]() 
    clientSectionTitles = [String]() 

    clients.sortInPlace ({ $0.lastName < $1.lastName }) 

    for c in clients { 
     let clientName = "\(c.lastName), \(c.firstName)" 

     // Get the first letter of the name and build the dictionary 
     let clientKey = clientName!.substringToIndex(clientName!.startIndex.advancedBy(1)) 
     if var clientValues = clientDict[clientKey] { 
      clientValues.append(c) 
      clientDict[clientKey] = clientValues 
     } else { 
      clientDict[clientKey] = [c] 
     } 
    } 

    // Get the section titles from the dictionary's keys and sort them in ascending order 
    clientSectionTitles = [String](clientDict.keys) 
    clientSectionTitles = clientSectionTitles.sort { $0 < $1 } 
} 

Cependant, cette ligne a été la clé de la solution:

let clientDict = [String: [Client]]()