Как я могу группировать элементы TableView из словаря в swift?

Давайте рассмотрим этот пример:

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 ????
    }
}

предположим, что нам нужны ключи (фрукты и овощи) словаря - это количество разделов, плюс они будут названиями разделов. Элементами клавиш (например, яблок и бананов) будут строки каждого раздела. Как я могу реализовать это в своем коде? Я знаю, что это может быть легко, но я не мог понять это сам.

Ответ 1

Вы можете использовать struct для этого, и вот пример:

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

Ответ 2

Swift 2

ваш словарь

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

Ваша таблица

 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 
}

Ответ 3

Из документации Apple:

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

Description: коллекция, содержащая только ключи от себя. Клавиши отображаются в том же порядке, что и в качестве члена пары ключ-значение .0. Каждый ключ в результате имеет уникальное значение.

names.keys.array возвращает Array ключей.

SO:

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

Это будет работать с любым словарем с любым количеством данных (даже если это неизвестно программисту

Ответ 4

Все типы коллекций должны быть массивом

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

Ответ 5

Если вы хотите, чтобы он отсортировал, используйте глобальную сортированную функцию для сортировки словаря.

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