我正在测试一些代码,在iOS13中,UICollectionViewFlowLayout似乎没有在collectionView框架中接收更改。
下面是一个示例代码,其中我只是根据我在collectionView下面的tableview中滚动的数量来更改collectionView的高度:
ViewController
func scrollViewDidScroll(_ scrollView: UIScrollView) {
collectionView.collectionViewLayout.invalidateLayout()
let totalScroll = scrollView.contentSize.height - scrollView.bounds.size.height
let offset = (scrollView.contentOffset.y)
let percentage = offset / totalScroll
var frame = collectionView.frame
frame.size.height = 40 - (40 * percentage)
collectionView.frame = frame
}
CustomCollectionViewFlowLayout:UICollectionViewFlowLayout
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let attributes = super.layoutAttributesForElements(in: rect)
print(collectionView?.frame)
return attributes
}
iOS 12及以下版本的CustomCollectionViewFlowLayout内部的print语句正确打印出collectionView.frame中的更改,即高度实际更改。但是在iOS 13中,它根本没有得到体现。
帮助任何人?
首先,
func scrollViewDidScroll(_ scrollView: UIScrollView) {
collectionView.collectionViewLayout.invalidateLayout()
...
}
看起来可疑。确定要在scrollViewDidScroll
函数中使布局无效吗?
有一个适当的位置,在滚动时应该使布局无效:
final class CustomCollectionViewFlowLayout: UICollectionViewFlowLayout {
override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
// proper place to invalidate layout while scrolling
}
}
如果在布局类中使布局无效,则可以正确计算所需的布局容器高度。然后,您可以通知您的集合视图其高度应更改。例如,在某些代表的帮助下:
protocol CustomCollectionViewFlowLayoutSizeDelegate: class {
func newSizeAvailableFor(layout: CustomCollectionViewFlowLayout, progress: CGFloat)
}
final class CustomCollectionViewFlowLayout: UICollectionViewFlowLayout {
weak var sizeDelegate: CustomCollectionViewFlowLayoutSizeDelegate?
override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
// proper place to invalidate layout while scrolling
}
}
final class CustomViewController: CustomCollectionViewFlowLayoutSizeDelegate {
func newSizeAvailableFor(layout: CustomCollectionViewFlowLayout, progress: CGFloat) {
// change collectionView frame
}
}
结论:
您的布局正尝试收听其容器高度,但是其容器高度是根据您的布局计算的。您可以轻松地删除容器依赖关系以进行高度计算,或者只为布局提供初始容器高度。最后,布局将负责所有计算。