如何在 UITableView 内的 UICollectionView 内获取数组数组并返回正确数量的项目?

Posted

技术标签:

【中文标题】如何在 UITableView 内的 UICollectionView 内获取数组数组并返回正确数量的项目?【英文标题】:How to get an array of arrays inside of UICollectionView that's inside a UITableView and also return the correct number of items? 【发布时间】:2019-03-28 08:45:06 【问题描述】:

我目前正在尝试弄清楚如何使用 UICollectionView 获取 UITableView 以在 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 中滚动。

下面是代码。

视图控制器

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()
    

CollectionViewCell

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

最后是填充 UICollectionView 数据的 TableViewCell 文件。

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。

回顾一下,我无法在集合视图单元格中显示数据以及设置每个部分的项目数,如果添加更多数据会自动调整。

感谢您的宝贵时间,我真的很感激。

【问题讨论】:

【参考方案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]
        cell.collectionView.reloadData()

        return cell
    
    return UITableViewCell()

除此之外,你还应该考虑vadian的回答。

【讨论】:

【参考方案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 这是虚拟数据,该部分将是您的 API 模型,因此它是动态的,您无需担心。 当然你可以动态填充数据源。将 sections 声明为 var 并附加项目或将 API 响应直接映射到 Section 项目。根据数据模型,而不是数组数组将数据作为 JSON 字典数组发送。 忽略节标题。我只是真的在尝试 API 数据([[“food 1”,“food 2”,“food 3”],[“car 1”,“car 2”,“car 3”,“car 4”],[ “房子 1”、“房子 2”]、[“人 1”、“人 2”、“人 3”、“人 4”]、[“孩子 1”、“孩子 2”、“孩子 3”、“ child 4", "kid 5"]] ) 到 UICollectionView 单元格中。但是,此响应可以在数组内部包含更多数组,并且可以在数组内部包含更多数组。我只是不知道如何获取数据以正确填充集合视图。我提供的数据被替换为虚拟数据,但它的格式与我从 api 接收它的方式完全相同。 我只是不太明白,抱歉。

以上是关于如何在 UITableView 内的 UICollectionView 内获取数组数组并返回正确数量的项目?的主要内容,如果未能解决你的问题,请参考以下文章

如何同步 UICollectionViewCell 内的 UITableView 之间的滚动(在 UICollectionViewController 内)

如何在 UITabBarViewController 内的 UINavigationController 内调整 UITableView 的大小?

如何在 UITableView 内的 UICollectionView 内获取数组数组并返回正确数量的项目?

如何添加拉表视图以刷新 uitableview 内的数据

UIViewController 内的 UITableView? [关闭]

如何检测 UIViewController 内的 UITableView 类?