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.
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
}
}
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
}
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
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
}
}
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]
}
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
}