В настоящее время я пытаюсь выяснить, как получить 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"]]
У меня заголовки выглядят нормально, как показано ниже.
Однако, когда я прокручиваю по горизонтали внутри UICollectionViews, данные перепутаются. Это видно как на снимках экрана выше, так и ниже, потому что я прокручивал верхний UICollectionView.
Вот следующий код.
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.
Напомним, что у меня возникли проблемы с отображением данных в ячейках представления коллекции, а также с установкой количества элементов в разделе таким образом, чтобы автоматически корректироваться при добавлении дополнительных данных.
Спасибо за ваше время, я очень ценю это.





Вы имеете дело с объектно-ориентированным языком. Воспользуйтесь этим и используйте пользовательскую структуру
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
}
@Ron Это фиктивные данные, этот раздел будет вашей моделью API, поэтому он динамический, и вам не нужно об этом беспокоиться.
Конечно, вы можете заполнить источник данных динамически. Объявите sections как var и добавьте элементы или сопоставьте ответ API непосредственно с элементами Section. Вместо массива массивов отправляйте данные в виде массива словарей JSON в соответствии с моделью данных.
Игнорирование заголовков разделов. Я просто действительно пытаюсь получить данные API ([["еда 1", "еда 2", "еда 3"], ["автомобиль 1", "автомобиль 2", "автомобиль 3", "автомобиль 4"], [ "дом 1", "дом 2"], ["человек 1", "человек 2", "человек 3", "человек 4"], ["ребенок 1", "ребенок 2", "ребенок 3", " kid 4", "kid 5"]] ) в ячейки UICollectionView. Однако этот ответ может содержать больше внутри массивов и может содержать больше массивов внутри массива. Я просто не знаю, как заставить данные правильно заполнять представления коллекции. Данные, которые я предоставил, заменены фиктивными данными, но они отформатированы именно так, как я получаю их из API.
Я просто не совсем понимаю, извините.
Из-за повторного использования ячеек вам необходимо перезагрузить представление коллекции, когда ячейка табличного представления удалена из очереди:
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.
Но что, если я анализирую API или пользователь должен добавить еще один раздел с новыми элементами? Итак, вместо еды, машин, домов, людей и детей; это будет еда, автомобили, дома, люди, дети и ноутбуки. Где у ноутбуков тоже был бы свой набор предметов. Как я могу заставить ваши «разрешить разделы» автоматически обновляться на основе ответа массива массивов?