效果图
需求
最近项目中遇到一个需求,点击cell来改变cell大小。被点击的cell不仅要改变大小,还要处于屏幕最中间。
解决思路
最开始想到的解决方案就是改变collectionView的layout中的itemSize属性,同时设置collectionView的contentOffset
或者用scrollToItemAtIndexPath
方法。但是做的过程中有这样几个问题:
- itemSize不能超过collectionView的size,虽然运行时不会崩溃,但是控制台会输出警告,并且改变效果不会达到预期值;
- 如果单纯的使用itemSize来改变cell大小,也只是以cell的左边缘为准向右变大,不能满足从中心到两侧变大的条件。而且在改变itemSize之后,滑动collectionView会使得画面有闪屏出现。
- 工程用
storyboard
来展示UI,使用autolayout
进行布局,所以更改collectionView大小时需要执行ifNeedLayout()
方法。由此也可能引起collectionView闪烁
在完成这种改变size以及contentOffset
的方式之后,发现动画效果与预期相差太远,不能完全满足需求。之后再objc.io找到了更好的解决思路。就是自定义UICollectionViewFlowLayoutt
,使用系统提供的动画效果,就可以很轻松的实现想要的效果。
实现
根据需求自定义的UICollectionViewFlowLayout
需要重写两个方法:
shouldInvalidateLayoutForBoundsChange
targetContentOffsetForProposedContentOffset
由于改变layout的size必须小于collectionView的容器大小,因此效果看起来像是cell紧贴collectionView上侧向下延伸变大,第一个方法则用来将cell固定在底部,让cell在视觉上从底部向上变大。第二个方法则是在更改layout或者刷新layout之后来决定collectionView滑动位置,根据当前的cell的size以及各个cell的间距就可以得出。
注意:Demo仅仅用于参考,有些坑没有填,需要自行修改。
需要填的坑
- 当在普通起初状态时,如果cell个数小于3个的时候,collectionView背景透明,但是无法响应父试图点击事件,需要根据情况修改。
- cell个数小于3个时,不能滑动,这里需要动态修改collectionView的contentSize。
TODO:
之后需要学习的就是滑动变化大小。