【问题标题】:UIcollectionview Update cell heightUIcollectionview 更新单元格高度
【发布时间】:2020-02-06 17:17:38
【问题描述】:

目前我正在研究一种集合视图的动态布局。

在collectionview单元格内的某些点击(前单元格有UIbutton)该点击按钮的单元格应该增加高度。

我已经实现了collectionviewflowlayoutdelegate的方法 SizeforItemAt:

当单击单元格按钮时,我只是重新加载特定的一个索引路径 self.collectionview.reloadItems([indexpath])

它将调用 SizeforItemAt: 但它再次调用所有单元格。因此,由于这个原因,我的 collectionview 在大小更新时会抖动所有单元格。

那么有没有办法只更新单个单元格的高度?

【问题讨论】:

    标签: ios swift4


    【解决方案1】:

    你可以这样做

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize{
        let width = collectionView.bounds.width
        let height = 0.0
        // for specific cell  height
        if indexPath.row == 1{
            height = 200.0 // chnage height for a specific cell
        }else{
            height = collectionView.bounds.height //actual height
        }
        return CGSize(width: width, height: width)
    }
    
    

    更新

    我不确定单击按钮时它是否有效。

    但是您可以通过实现didSelectItemAt 来更改选定的特定单元格的高度,如下所示。

    override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    
        collectionView.performBatchUpdates(nil, completion: nil)
    
        // to reload specific cell use below line. 
        //collectionView.reloadItemsAtIndexPaths([indexPath])
    }
    

    您可以检查sizeForItemAt中的idexPath是否被选中。如果它被选中,那么您可以更改高度,否则返回原始高度。像下面这样。

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    
        switch collectionView.indexPathsForSelectedItems?.first {
        case .some(indexPath):
            let height = 200.0 // here you can change the height for selected cell.
            return CGSize(width: view.frame.width,height: height) 
        default:
            let height = 200.0 // standard height
            return CGSize(width: view.frame.width, height: height)
        }
    }
    

    【讨论】:

    • 不,兄弟,你没有得到我的问题。当我根据我将从 api 获得的内容增加单元格大小时。然后点击按钮后,它应该只增加一个单元格的大小。所以 SizeforItemAt 方法应该只调用一个单元格。
    • @Jaimish “所以 SizeforItemAt 方法应该只调用一个单元格” 您正在以一种奇怪的方式使用“应该”这个词。如何调用sizeForItemAt 不取决于。你的工作是在它调用时正确处理它。
    • @JakirHossain 如果我为某些 indexpath 数组重新加载项目怎么办。对于哪个 indexpath sizeforItemAt: 将调用?只有那些 indexpath 还是全部?
    【解决方案2】:

    那么有没有办法只更新单个单元格的高度?

    没有。如果实现了sizeForItemAt:,则可以并且将为运行时希望的任何单元格调用它。这不取决于你这是什么细胞。你的工作是为有问题的单元格返回正确的值。如果您不想更改单元格的高度,请不要更改它,但您无法阻止呼叫到达。

    但是,我怀疑这与您的问题有关。听起来您想要更新这个单元格的高度是一种平滑(动画)的方式。这和你问的无关。

    【讨论】:

    • 理解并同意,但我正在调用 reloadItems 并传递我想要重新加载和更新高度的特定索引路径,当时为什么它为所有单元格调用 sizeForItemAt:。它应该只调用我在重新加载时传递给的那些索引路径。希望你明白我的意思。 :)
    • 再一次,您所说的涉及“应该”的奇怪用法。您可能的意思是“我希望它可以那样工作”。但我告诉你不是。即使仅重新加载一个单元格,也会重新计算所有高度。这就是事实。你可以随心所欲地说“应该”:它不会改变任何现实。
    • 对不起,应该说,当我点击单元格上的某个按钮并更新高度时,我实际上面临着 jurking 的问题。正是希望在集合视图中以适当的滚动和平滑展开折叠类的东西。接受集合视图给出的现实
    • 是的,这就是我们所说的 x-y 问题。与其问如何只更新一个单元格的高度,不如问如何平滑地更新一个单元格的高度。
    【解决方案3】:

    检查集合视图单元格的动态高度。

    并且不要对单元格的高度进行硬编码,而是让单元格内的组件定义单元格的高度。这样,当点击按钮时,实用地增加/减少该单元格内某些组件的大小,您将获得所需的结果。

    【讨论】: