Выводим элементы словаря в таблицу


#1

Имеем простой словарь [string:string], его нужно вывести в ячейках таблицы картинкой и текстом. В словаре ключ - это название группы, отображаем в лэйбле. Значение - название картинки, которую отображаем в imageview. Как правильно вызывать ключ и значение в таблице?

    var group = ["Алкогольные напитки" : "alco","Аптека" : "pharm","Газеты, книги, музыка" : "book","Готовые блюда" : "meal"] 
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! CorrectGroupCell
    
    cell.groupLabel.text =      ?
    cell.groupImage.image = UIImage(named:      ?
    return cell
}

#2

У меня нету возможности проверить код, но скорее всего так

let dict = group[indexPath.row]
cell.groupLabel.text = dict.key
cell.groupImage.image = UIImage(named: dict.value)

#3

Наверно правильно использовать массив)) т.к. словарь в Swift является неупорядоченной коллекцией. Например массив кортежей (можно и словарей кстате)

    var group = [("Алкогольные напитки", "alco"),("Аптека", "pharm"),("Газеты, книги, музыка", "book"),("Готовые блюда", "meal")]
    cell.groupLabel.text = group[indexPath.row].0
    cell.groupImage.image = UIImage(named: group[indexPath.row].1)

Но если очень нужно именно словарь, можно попробовать так

let name = [String](group.keys) // создаем массив из keys словаря
let image = [String](group.values) // создаем массив из values словаря
cell.groupLabel.text = name[indexPath.row]
cell.groupImage.image = UIImage(named: image[indexPath.row])

#4

Всем большое спасибо!


#5

Подскажи пожалуйста, а если сложнее словарь, типа

var nameOfLists: [String: [String]] = [:]

То как вывести values в таблице? По предыдущему твоему примеру для вывода значения ключей отлично работает, а для значений не подходит. Спасибо


#6

Давайте немного подскажу. Имеем

    var nameOfLists: [String: [String]] = [:]
    или для простоты
    var nameOfLists: [String: [String]] = ["люди":["Вася", "Петя", "Еще кто-то"], "собаки" : ["жучка","мухтар"]]

так вот в словаре мы можем получить значение по ключу

      let value = namrOfLists["люди"]

а вот тип value будтет [String], так как в словаре [String: [String]]

     [String: [String]]       key: String, value: [String]

ну а дальше как вы и писали

    cell.contentOfListLabel?.text = value[indexPath.row]

#7

Ну а если содержимое словаря передается на этот контроллер из другого и название ключей множество, не конкретно один какой-то , то как value описать? Мой пример ниже не работает

let listName = [String](nameOfLists.keys)
let value = nameOfLists["\(listName)"]

cell.contentOfListLabel?.text = value?[indexPath.row]

#8

Хорошая практика готовить массив с нормальными модельками данных, а не словарями.

struct SomeModel {
    var someName: String
    var otherValue: String
    var integerValue: Int
}

let arrayForTable = [SomeModel]()

Уже после при возврате ячейки, как тупой пример:

cell.configure(name: arrayForTable[indexPath.row].someName, value: arrayForTable[indexPath.row].otherValue, intValue: arrayForTable[indexPath.row].integerValue)

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


#9
 let listName = [String](nameOfLists.keys)

что вы хотите сделать в этой строчке?


#10

Я просто переменной присвоил массив из ключей, чтобы после получать соответствующие значения к этим ключам


#11

Не могу нагуглить примеров с configure…


#12

Это кастомный метод для заполнения ячейки, который создается в ShoppingListcell


#13

Каким образом правильно этот метод реализовать в ShoppingListcell и каким образом его вызывать уже в самом контроллере? Нет примеров… Спасибо


#14

Я же говорю - это кастомный метод. Вам самим нужно его написать и всю логику в нем, все что вы хотите сделать с ячейкой. Можете назвать его как угодно: configure, bind, zapolnit…


#15

это прям новый синтаксис))

  let listName = nameOfLists.keys - вот и все, зачем вам [String]?

Ваш второй вопрос.

в Вашем класс ячейки добавьте что-то похожее на метод:

  func configure(name: String, other: String){
          youFirstLabel.text = name
          youSecondLabel.text = other
  }

и потом можете его вызывать в методе cellForRow at IndexPath вот так как пробуете на том скрине что скинули


#16

Добавил в класс ячейки

func configure(name: String, content: [String]){ nameOfListLabel.text = name contentOfListLabel.text = "\([content])" }
но выдает ошибку при запуске


Это потому, что у меня нет значений самих listName и listValue? И каким тогда способом можно присвоить им значения? Спасибо


#17

Судя по всему у вас в методе numberOfRows не верно возвращается кол-во ячеек.

И данный метод можно немного упростить и сделать читабельнее

tableView() -> UITableViewCell {
   ...
   let data = arrayForTable[indexPath.row]

   cell.configure(name: data.listName, content: data.listValue)

   ...
}

#18

Сейчас все подправил, теперь отлично, но так и не разобрался как добавлять значения listName и listValue. Для теста добавил значения, но при запуске строки отображаются пустыми

var data = arrayForTable[indexPath.row]
    data.listName = "Люди"
    data.listValue = ["Андрей", "Сергей"]
    
    cell.configure(name: data.listName, content: data.listValue)

Помогите плиз разобраться с добавлением значений. Спасибо


#19

Значения добавляйте при инициализации переменной.


#20

так, вы меня окончательно запутали. А где вы должны брать эти значения?