Как получить массив массивов внутри UICollectionView, который находится внутри UITableView, а также вернуть правильное количество элементов?

В настоящее время я пытаюсь выяснить, как получить UITableView с UICollectionView, чтобы правильно отображать следующий набор данных внутри UICollectionViews.

[["food 1", "food 2", "food 3"], ["car 1", "car 2", "car 3", "car 4"], ["house 1", "house 2"], ["person 1", "person 2", "person 3", "person 4"], ["kid 1", "kid 2", "kid 3", "kid 4", "kid 5"]]

У меня заголовки выглядят нормально, как показано ниже.

Как получить массив массивов внутри UICollectionView, который находится внутри UITableView, а также вернуть правильное количество элементов?

Однако, когда я прокручиваю по горизонтали внутри UICollectionViews, данные перепутаются. Это видно как на снимках экрана выше, так и ниже, потому что я прокручивал верхний UICollectionView.

Как получить массив массивов внутри UICollectionView, который находится внутри UITableView, а также вернуть правильное количество элементов?

Вот следующий код.

ViewController

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

    let section = ["foods","cars","houses","persons","kids"]

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.estimatedRowHeight = 122
        tableView.tableFooterView = UIView()
    }
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return self.section[section]
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return section.count
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = tableView.dequeueReusableCell(withIdentifier: "tableViewCell", for: indexPath) as? TableViewCell
        {
            data = [["food 1", "food 2", "food 3"], ["car 1", "car 2", "car 3", "car 4"], ["house 1", "house 2"], ["person 1", "person 2", "person 3", "person 4"], ["kid 1", "kid 2", "kid 3", "kid 4", "kid 5"]][indexPath.section]

            return cell
        }
        return UITableViewCell()
    }
}

КоллекцияViewCell

class CollectionViewCell: UICollectionViewCell {
    @IBOutlet weak var dataLabel: UILabel!
    override func awakeFromNib() {
        super.awakeFromNib()
    }
}

Наконец, файл TableViewCell, заполняющий данные UICollectionView.

var data = [String]()

class TableViewCell: UITableViewCell, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

    @IBOutlet weak var collectionView: UICollectionView!

    let collCount = Int()
    //var imageArray = [[String]] ()
    override func awakeFromNib() {
        super.awakeFromNib()
        self.collectionView.delegate = self
        self.collectionView.dataSource = self

    }
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 3 //should return the amount of data per array
    }
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        if let cell: CollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath) as? CollectionViewCell
        {

            cell.dataLabel.text = data[indexPath.item]

            return cell
        }
        return UICollectionViewCell()
    }
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize{
        let size = CGSize(width: 256, height: 100.5)
        return size
    }
}

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

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 3 //should return the amount of data per array in the array of data
    }

Данные...

[["food 1", "food 2", "food 3"], ["car 1", "car 2", "car 3", "car 4"], ["house 1", "house 2"], ["person 1", "person 2", "person 3", "person 4"], ["kid 1", "kid 2", "kid 3", "kid 4", "kid 5"]]

... может в конечном итоге получить больше данных, чем то, что дано в настоящее время. Например, индекс 0 в этом массиве может иметь 4 вместо текущих 3.

Напомним, что у меня возникли проблемы с отображением данных в ячейках представления коллекции, а также с установкой количества элементов в разделе таким образом, чтобы автоматически корректироваться при добавлении дополнительных данных.

Спасибо за ваше время, я очень ценю это.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
888
2

Ответы 2

Вы имеете дело с объектно-ориентированным языком. Воспользуйтесь этим и используйте пользовательскую структуру

struct Section {
    let title : String
    let items : [String]
}

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    let sections = [Section(title: "foods", items: ["food 1", "food 2", "food 3"]),
        Section(title: "cars", items: ["car 1", "car 2", "car 3", "car 4"]),
        Section(title: "houses", items: ["house 1", "house 2"]),
        Section(title: "persons", items: ["person 1", "person 2", "person 3", "person 4"]),
        Section(title: "kids", items: ["kid 1", "kid 2", "kid 3", "kid 4", "kid 5"])]

...

Например, это методы делегата, связанные с табличным представлением. Эквиваленты представления коллекции очень похожи

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return sections[section].title
}

func numberOfSections(in tableView: UITableView) -> Int {
    return sections.count
}

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
    // force unwrap the cell. Any crash reveals a design mistake
    let cell = tableView.dequeueReusableCell(withIdentifier: "tableViewCell", for: indexPath) as! TableViewCell
    let section = sections[indexPath.section]
    cell.dataLabel.text = section.items[indexPath.row]
    return cell
}

Но что, если я анализирую API или пользователь должен добавить еще один раздел с новыми элементами? Итак, вместо еды, машин, домов, людей и детей; это будет еда, автомобили, дома, люди, дети и ноутбуки. Где у ноутбуков тоже был бы свой набор предметов. Как я могу заставить ваши «разрешить разделы» автоматически обновляться на основе ответа массива массивов?

Ron 28.03.2019 10:02

@Ron Это фиктивные данные, этот раздел будет вашей моделью API, поэтому он динамический, и вам не нужно об этом беспокоиться.

dahiya_boy 28.03.2019 10:03

Конечно, вы можете заполнить источник данных динамически. Объявите sections как var и добавьте элементы или сопоставьте ответ API непосредственно с элементами Section. Вместо массива массивов отправляйте данные в виде массива словарей JSON в соответствии с моделью данных.

vadian 28.03.2019 10:04

Игнорирование заголовков разделов. Я просто действительно пытаюсь получить данные API ([["еда 1", "еда 2", "еда 3"], ["автомобиль 1", "автомобиль 2", "автомобиль 3", "автомобиль 4"], [ "дом 1", "дом 2"], ["человек 1", "человек 2", "человек 3", "человек 4"], ["ребенок 1", "ребенок 2", "ребенок 3", " kid 4", "kid 5"]] ) в ячейки UICollectionView. Однако этот ответ может содержать больше внутри массивов и может содержать больше массивов внутри массива. Я просто не знаю, как заставить данные правильно заполнять представления коллекции. Данные, которые я предоставил, заменены фиктивными данными, но они отформатированы именно так, как я получаю их из API.

Ron 28.03.2019 10:26

Я просто не совсем понимаю, извините.

Ron 28.03.2019 10:26

Из-за повторного использования ячеек вам необходимо перезагрузить представление коллекции, когда ячейка табличного представления удалена из очереди:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if let cell = tableView.dequeueReusableCell(withIdentifier: "tableViewCell", for: indexPath) as? TableViewCell
    {
        data = [["food 1", "food 2", "food 3"], ["car 1", "car 2", "car 3", "car 4"], ["house 1", "house 2"], ["person 1", "person 2", "person 3", "person 4"], ["kid 1", "kid 2", "kid 3", "kid 4", "kid 5"]][indexPath.section]
        cell.collectionView.reloadData()

        return cell
    }
    return UITableViewCell()
}

Кроме того, вы также должны рассмотреть ответ vadian.

Другие вопросы по теме