• 自定义UICollectionViewLayout之CATransform3D


    1、自定义UICollectionViewLayout旋转效果

      之前有自定义UICollectionViewLayout(适用于多个section),本文是一个对cell进行CATransform3D操作的自定义!

    2、相关代码

    #import "CollectionFlowLayout.h"
    
    @interface CollectionFlowLayout()
    //存放每一个cell的属性
    @property (nonatomic, retain) NSMutableArray *attributesArray;
    
    @end
    
    @implementation CollectionFlowLayout
    /**
     重写系统prepareLayout方法 (设置item的坐标等属性)
     */
    - (void)prepareLayout{
        [super prepareLayout];
        _attributesArray = [[NSMutableArray alloc] init];
        CGFloat inset  = self.collectionView.bounds.size.width * (6/64.0f);
        inset = floor(inset);
        self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
        CGFloat totalWidth = self.collectionView.frame.size.width;
        self.collectionView.pagingEnabled = YES;
        
        NSUInteger  itemCount = [self.collectionView numberOfItemsInSection:0];
        for (int i=0; i<itemCount; i++) {
            NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
            UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
            CGFloat baseOffsetForCurrentView =  i* self.collectionView.bounds.size.width;
            CGFloat currentOffset = self.collectionView.contentOffset.x;
            //通过偏移量currentOffset 和baseOffsetForCurrentView 差值 得到collectionView宽度的倍数
            //例如:当row为2时,是第三行,baseOffsetForCurrentView是: width*2 偏移量是 :width*2
            //     滑动到第二行时 偏移量为:width,角度计算为 (width-width*2)/width 为-0.5
            //     滑动到第四行时 偏移量为:width*3,角度计算为 (width*3-width*2)/width 为0.5
            //     所以角度为 -0.5 —— 0.5变化,通过第二行和第四行的正负判断是左划还是右划确定axis值
            attributes.transform3D = [self transformfromAngle:(currentOffset-baseOffsetForCurrentView)/totalWidth/2 xAxis:(currentOffset-baseOffsetForCurrentView)>0?YES:NO];
            attributes.frame = CGRectMake(inset+(totalWidth)*i, 0, self.collectionView.bounds.size.width - (2 *inset), self.collectionView.bounds.size.height * 3/4);
            [_attributesArray addObject:attributes];
        }
    
    }
    
    /**
     当collection view的bounds改变时,布局需要告诉collection view是否需要重新计算布局
     */
    - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
        return YES;
    }
    
    
    /**
     3D动画
     */
    - (CATransform3D)transformfromAngle:(CGFloat )angle xAxis:(BOOL)axis
    {
        CATransform3D t = CATransform3DIdentity;
        t.m34  = 1.0/-500;
        t = CATransform3DRotate(t,angle, axis?1:-1,1, 0);
        return t;
    }
    
    
    
    /**
     返回collectionView的界面显示大小
     */
    - (CGSize)collectionViewContentSize{
        return  CGSizeMake(self.collectionView.frame.size.width*[self.collectionView numberOfItemsInSection:0], self.collectionView.frame.size.height);
    }
    
    /**
     将所有的layoutAttributes重写布局
     */
    - (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{
        return _attributesArray;
    }
    @end
  • 相关阅读:
    rider中的gitbash如何从上次退出的目录启动
    docker swarm外部验证负载均衡时不生效
    css做一个可以变成关闭图标的菜单按钮
    mac外接键盘HOME,END键问题
    kubernetes实践录 使用Baget部署一个私有Nuget仓库
    C#中正确的实现IDisposable接口以释放非托管资源
    网络磁盘nfs使用笔记
    EFCore分组查询(GroupBy)后获取第一个元素
    Angular踩坑ExpressionChangedAfterItHasBeenCheckedError异常
    写了个适用于vscode的minio图床客户端插件 vscodeminiopicman
  • 原文地址:https://www.cnblogs.com/xianfeng-zhang/p/8743221.html
Copyright © 2020-2023  润新知