使用collectionView(_:layout:sizeForItemAt :)调整UICollectionView单元的大小,而无需调用reloadData()

时间:2019-08-05 01:55:13

标签: ios swift uicollectionview uicollectionviewcell uicollectionviewflowlayout

我正在尝试实现一个UICollectionViewCell,其中包括一个UITextView,它会在运行时随着用户输入的文本量的增加而调整大小,并根据其上下移动单元格在文本框的大小上。 (此UICollectionView通过UICollectionViewDelegateFlowLayout实现)

当用户通过textViewDidChange()的{​​{1}}方法向单元格中输入文本时,我可以在运行时调整实际单元格的大小。但是,这不会更改其他单元格的位置,因为不会立即调用UITextViewDelegate。如果我在collectionView(\_:layout:sizeForItemAt:)类中调用reloadData(),则能够触发collectionView(_:layout:sizeForItemAt :),这将相对于感兴趣的单元格重新定位其他单元格,但是这样做的问题是这样会重新加载所有对象,然后立即关闭键盘。

是否可以在不调用UICollectionView的情况下触发collectionView(_:layout:sizeForItemAt:)

另一个我想知道的问题是Resize CollectionView Cell during runtime without reloading,但他们的问题也没有得到答案。

1 个答案:

答案 0 :(得分:1)

我不确定您的触发事件是如何调整大小的,但是我能想到的最简单的方法是将对collectionView的 weak 引用传递给collectionViewCell当您创建它时。确保它很弱,因为细胞一直在被创建和破坏,并且您不希望有保留周期。

一种方法可能是仅将didSet用于该单元格的bounds。我认为在初始化单元格时这不会做任何事情,但是每当单个单元格的边界发生变化时,您都可以在那里调用方法。我还没有测试这种方法,但是我认为这是一种懒惰,低举,最小的簿记解决方案。

这里是“诗人物理学”的样子:

class YourCell: UICollectionViewCell {

    weak var collectionView: UICollectionView?

    // Whatever other stuff you need on your cell

    override var bounds: CGRect {
        didSet {
            // Whenever the bounds get set, the collectionView's layout will be invalidated.
            invalidateCollectionViewLayout()
        }
    }

    private func invalidateCollectionViewLayout() {
        guard let collectionView = collectionView else { return }
        collectionView.collectionViewLayout.invalidateLayout()
    }
}