自定义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

 

posted @ 2018-04-08 10:06  ForeverGuard  阅读(592)  评论(0编辑  收藏  举报