简体   繁体   English

Tableview中的CollectionView,数据源错误

[英]CollectionView inside Tableview, error with datasource

i have a uiviewcontroller, where i put a uitableview, with custom cells. 我有一个uiviewcontroller,在其中放置了一个带有自定义单元格的uitableview。 Each of these cells, have inside a uicollectionview, with a horizontal scrolling. 这些单元格中的每个单元格都在uicollectionview内部,并且具有水平滚动。

I am working programmatically, so the tableviewcell is the delegate/datasource for collectionview. 我正在以编程方式工作,因此tableviewcell是collectionview的委托/数据源。

My datasource structure, is an array of arrays . 我的数据源的结构,是一个数组数组

My tableview, has, for every tableviewcell, a tableview section.Tableview datasource methods work without problem using the array . 我的tableview对于每个tableviewcell都有一个tableview部分。Tableview数据源方法可以使用array正常工作。 I am able to set up the tableview correctly. 我能够正确设置tableview。 Inside this cell, i want to display a collectionview, with horizontal scrolling. 在此单元格内,我想显示一个collectionview,并进行水平滚动。

The problem which i am encountering is i cannot assign datasource correctly using the arrays to collectionview. 我遇到的问题是我无法使用数组正确地将数据源分配给collectionview。 What happens is when i load the tableview, and scrolling down, i see duplicate records, so for example the first 3 rows are displayed correctly(in terms of data and number of items),but from the 4th row, for example, data is duplicated, so i see again the records for the first 3 rows, and of course this does not have to happen, because if i scroll on the 4th line(the collectionview on the 4th row) the app crashes due to an index problem out of range. 发生的情况是,当我加载表格视图并向下滚动时,我看到重复的记录,因此例如前3行正确显示(根据数据和项数),但从第4行开始显示,例如复制的,所以我再次看到了前3行的记录,当然这不必发生,因为如果我在第4行(第4行的collectionview)上滚动,则应用会由于索引问题而崩溃范围。

This is simple to understand: lets say i have 10 cells on the first row, and 5 on the 4th row/or section, as you prefer... Scrolling the 4th row'scollection view will cause the crash. 这很容易理解:假设您愿意,我在第一行有10个单元格,在第四行或每个部分有5个单元格...滚动第四行的collection视图将导致崩溃。 This is because of the wrong data which is actually the same from the first row: instead, i have only 5 cells to render... 这是因为错误的数据实际上与第一行的数据相同:相反,我只有5个单元格要渲染...

Tecnique i am using is pretty simple: give each tableviewcell's tag the actual indexpath.section. 我正在使用的Tecnique非常简单:为每个tableviewcell的标签提供实际的indexpath.section。 Then in the collectionview, use this tag to loop through array and then the indexpath.item to get the correct array . 然后在collectionview中,使用此标记遍历array ,然后使用indexpath.item来获取正确的array

Lets get a look into the code now: 现在让我们看一下代码:

Tableview 泰伯维

func numberOfSections(in tableView: UITableView) -> Int {
    return DataManager.shared.datasource.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! DiarioTableViewCell
    cell.tag = indexPath.section

    return cell
}

TableviewCell TableviewCell

override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
    super.init(style: .default, reuseIdentifier: "cell")

    collectionView.register(DiarioCVCell.self, forCellWithReuseIdentifier: "cellCV")
    collectionView.delegate = self
    collectionView.dataSource = self

    DataManager.shared.istanzaCV = self.collectionView

    addSubview(tableCellBG)
    addSubview(collectionView)
    setConstraints()
}

CollectionView 的CollectionView

func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 1
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

    let tvCell = collectionView.superview as! DiarioTableViewCell
    return DataManager.shared.datasource[tvCell.tag].count

}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellCV", for: indexPath) as! DiarioCVCell

    let celltag = (collectionView.superview as! DiarioTableViewCell).tag

    cell.datasource = DataManager.shared.datasource[celltag][indexPath.item]

    return cell
}

Notice i have read all the possibly related threads, even ashfurrow's article, and here on stack, but i was not able to find a solution. 请注意,我已经阅读了所有可能相关的线程,甚至包括ashfurrow的文章,并且都放在此处,但是我找不到解决方案。 Thanks for any help! 谢谢你的帮助!

Try to reload your collection view when cell is showing. 显示单元格时,尝试重新加载您的收藏视图。 Cells are being reused to save memory so they are created only once - you are setting all data at init and it's staying there forever. 单元被重复使用以节省内存,因此它们只能创建一次-您在初始化时设置所有数据,并且数据将一直保留在那里。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! DiarioTableViewCell
    cell.tag = indexPath.section
    cell.collectionView.reloadData()
    cell.collectionView.collectionViewLayout.invalidateLayout() //just to be sure, maybe it's not necessary

    return cell
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM