UICollectionView布局cell的三种方式

UICollectionViewFlowLayout里面:

1 // 方法一
2 - (void)prepareLayout{}
3 // 方法二:可以修改宽度,不能修改高度
4 - (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect

贴出具体代码,注意方法二,要和一个带bool返回值的方法一块用:

 1 class CoverFlowLayout: UICollectionViewFlowLayout {
 2 
 3     // MARK: - 准备布局
 4     override func prepare() {
 5         super.prepare()
 6         
 7         scrollDirection = .horizontal
 8         
 9         let itemH = (collectionView?.bounds.size.height ?? 0) * 0.8
10         let itemW = itemH
11         itemSize = CGSize( itemW, height: itemH)
12         
13         minimumLineSpacing = 0
14     }
15     
16     // MARK: - 只要显示的区域发生变化,就重新计算布局
17     // true - 只要显示的区域发生改变,就让布局失效; -> 重新计算布局,执行下面的方法
18     override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
19         return true
20     }
21     
22     // MARK: - 布局某表Rect中的所有cell
23     override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
24         
25         // 先获取系统布局好的结果
26         let oldAttsArray = super.layoutAttributesForElements(in: rect)!
27         
28         // 创建新集合
29         var tempArray = [UICollectionViewLayoutAttributes]()
30         
31         // 遍历集合,进行修改
32         for oldAtt in oldAttsArray{
33         
34             // 这里不能直接修改,需先copy(否则控制台会输出错误)
35             let newAtt = oldAtt.copy() as! UICollectionViewLayoutAttributes
36             
37             // 屏幕中线位置
38             let screenCenterX = (collectionView?.bounds.size.width ?? 0) * 0.5 + (collectionView?.contentOffset.x ?? 0)
39             
40             // cell的中线
41             let itemCenterX = newAtt.center.x
42             
43             // 计算距离
44             let distance = screenCenterX - itemCenterX
45             
46             // 将距离转换成缩放比例
47             let scale = 1 - abs(distance) / (collectionView?.bounds.size.width ?? 1)
48             
49             let transform = CATransform3DIdentity
50             newAtt.transform3D = CATransform3DScale(transform, scale, scale, 1)
51                 
52             tempArray.append(newAtt)
53         }
54         
55         return tempArray
56     }
57     
58 }

协议方法 UICollectionViewDelegateFlowLayout:

 1 // 方法三:返回cell的size
 2 - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
 3     if (indexPath.section == 0) {  //第0组
 4         return CGSizeMake(collectionView.bounds.size.width, 100);
 5     }
 6    
 7     if (indexPath.section == 1 && indexPath.item == 0) {  //第一组的第0个
 8         return CGSizeMake(collectionView.bounds.size.width, 64);
 9     }
10    
11     CGFloat width = (collectionView.bounds.size.width - 1) / 2;
12     CGFloat height = 64;
13     return CGSizeMake(width, height);
14 }
原文地址:https://www.cnblogs.com/panda1024/p/6258640.html