我正在尝试实现一个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,但他们的问题也没有得到答案。
答案 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()
}
}