web-dev-qa-db-fra.com

Comment regrouper des éléments TableView d'un dictionnaire dans swift?

Considérons cet exemple: 

import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { 
    @IBOutlet weak var tableView: UITableView!

    var names = ["Vegetables": ["Tomato", "Potato", "Lettuce"], "Fruits": ["Apple", "Banana"]]

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

        let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier:"test")

    return cell
    }

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

    func sectionIndexTitlesForTableView(tableView: UITableView) -> [AnyObject]!{

    return ???
    }

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

supposons que nous ayons besoin que les clés (fruits et légumes) du dictionnaire soient le nombre de sections, plus ce seront les titres des sections. Les éléments des clés (par exemple, pommes et bananes) seront les rangées de chaque section. Comment puis-je implémenter cela dans mon code? Je sais que cela pourrait être facile mais je ne pouvais pas le comprendre moi-même.

14
Rami Ammoun

Vous pouvez utiliser struct pour cela et voici l'exemple:

import UIKit

class TableViewController: UITableViewController {

    var names = ["Vegetables": ["Tomato", "Potato", "Lettuce"], "Fruits": ["Apple", "Banana"]]

    struct Objects {

        var sectionName : String!
        var sectionObjects : [String]!
    }

    var objectArray = [Objects]()

    override func viewDidLoad() {
        super.viewDidLoad()

        for (key, value) in names {
            println("\(key) -> \(value)")
            objectArray.append(Objects(sectionName: key, sectionObjects: value))
        }
    }

    // MARK: - Table view data source

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

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return objectArray[section].sectionObjects.count
    }


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

        // Configure the cell...
        cell.textLabel?.text = objectArray[indexPath.section].sectionObjects[indexPath.row]
        return cell
    }

    override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {

        return objectArray[section].sectionName
    }
}
37
Dharmesh

Swift 2

vous exemple de dictionnaire

var dic:Dictionary<String,String> = ["key":"value","key1":"value2"]

Ta table

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

    var key   = Array(self.dic.keys)[indexPath.row]
    var value = Array(self.dic.values)[indexPath.row]
    cell.text = key + value 
}
22
Diego

De la documentation Apple: 

var keys: LazyForwardCollection<MapCollectionView<Dictionary<Key, Value>, Key>> { get }

Description: Une collection contenant uniquement les clés de self. Les clés apparaissent dans le même ordre qu’elles apparaissent en tant que membre .0 des paires clé-valeur dans self. Chaque clé du résultat a une valeur unique.

names.keys.array renvoie une Array des clés.

ALORS:

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return names.keys.array[section].count
}

func sectionIndexTitlesForTableView(tableView: UITableView) -> [AnyObject]!{
return names.keys.array
}

func tableView(tableView: UITableView,
    titleForHeaderInSection section: Int) -> String?{        
return names.keys.array[section]
}

Cela fonctionnera sur n'importe quel dictionnaire avec n'importe quelle quantité de données (même si le programmeur l'ignore

2
Raja Vikram

Si vous souhaitez le trier, utilisez la fonction de tri global pour trier le dictionnaire.

import UIKit

class TableViewController: UITableViewController {

    var names = ["Vegetables": ["Tomato", "Potato", "Lettuce"], "Fruits": ["Apple", "Banana"]]

    var namesSorted = [String, Array<String>]()

    override func viewDidLoad() {
        super.viewDidLoad()

        // Sort names
        namesSorted = sorted(names) { $0.0 < $1.0} // namesSorted = ["Fruits": ["Apple", "Banana"], "Vegetables": ["Tomato", "Potato", "Lettuce"]]

    }

    // MARK: - Table view data source

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

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return namesSorted[section].1.count
    }


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

        // Configure the cell...
        cell.textLabel?.text = namesSorted[indexPath.section].1[indexPath.row]
        return cell
    }

    override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {

        return namesSorted[section].0
    }
}
2
Santhosh

Tous les types de collection doivent être Array

var names = [["Tomato", "Potato", "Lettuce"], ["Apple", "Banana"]]
var sectionNames = ["Vegetables", "Fruits"]

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
  return names[section].count
}

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

func sectionIndexTitlesForTableView(tableView: UITableView) -> [AnyObject]!{

  return sectionNames
}

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

Un moyen plus simple de résoudre ce problème consiste à copier votre dictionnaire dans une variable temporaire. Utilisez removeFirst pour extraire les valeurs du tableau à l'intérieur du dictionnaire.

var itemList=["Grocery":["soap","flour","carrots"],"Vehicles":["oil change","gas","tire rotation"],"Household":["Cable","Tv","cellphone"]]
var itemListTmp :[String:[String]] = [:]

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text=itemListTmp[keysItem[indexPath.section]]?.removeFirst()
       //cell.textLabel?.text=itemList[indexPath.section].items[indexPath.row]
        return cell
    }

Une autre façon de résoudre ce problème consiste à extraire les clés et les valeurs dans des tableaux distincts:

var task=[String](itemList.keys)
var tobeDone=[[String]](itemList.values)
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return task[section]
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

    cell.textLabel?.text=tobeDone[indexPath.section][indexPath.row]

    return cell
}
0
pam