Swift之用CollectionViewFlowLayout实现LOL皮肤选择动画

最近看了一篇博文,用collectionView实现了一个很炫的界面,由于那个项目是用OC实现的,所以就想写一个swift分享给大家

参考原文:iOS开发之CollectionViewFlowLayout实现LOL皮肤选择动画

我们先来看一下效果:
效果图.gif

由于之前给大家分享过关于collectionView的创建和使用所以就不把创建collectionView的代码贴过来啦,大家想下载swift的源码可以加QQ群:512847147,里面还有很多实用的demo,想下载OC源码点击这里

首先自定义一个cardFlowLayout,继承于UICollectionViewFlowLayout
import UIKit

//完成一个过程需要的位移
let ACTIVE_DISTANCE = 200
let ZOOM_FACTOR = 0.3
//最大旋转角度
let ROTATE = 35.0*M_PI/180.0

class cardFlowLayout: UICollectionViewFlowLayout {

//设置基本大小
override func prepareLayout() {
    
    //cell的大小
    self.itemSize = CGSizeMake(300, 500)
    //滑动方向
    self.scrollDirection = UICollectionViewScrollDirection.Horizontal
    //组件四个方位间距
    self.sectionInset = UIEdgeInsetsMake(200, 50.0, 200, 50.0)
    //列间距
    self.minimumLineSpacing = 0.0
}
//允许更新位置
override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool {
    return true
}
//返回一个rect位置下所有的cell位置数组
//最重要的方法 返回当前矩形内所有的UICollectionViewLayoutAttributes
override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
    //得到所有的UICollectionViewLayoutAttributes
    let array = super.layoutAttributesForElementsInRect(rect)
    var visibleRect = CGRect()
    visibleRect.origin = self.collectionView!.contentOffset
    visibleRect.size = self.collectionView!.bounds.size
    
    for  attributes in array! {
        //cell中心离collectionView中心的位移
        //CGRectGetMidX表示得到一个frame中心点的X坐标
        let distance = CGRectGetMidX(visibleRect) - attributes.center.x
        
        //CGRectIntersectsRect 判断两个矩形是否相交
        //这里判断当前这个cell在不在rect矩形里
        if CGRectIntersectsRect(attributes.frame, rect) {
            let normalizedDistance = distance / CGFloat(ACTIVE_DISTANCE)
            
            //abs 绝对值
            //如果位移小于一个过程所需的位移
            if abs(distance)0) {
                    transfrom = CATransform3DRotate(transfrom, CGFloat(-ROTATE), 0.0, 1.0, 0.0)
                }else {//向左滑
                    transfrom = CATransform3DRotate(transfrom, CGFloat(ROTATE), 0.0, 1.0, 0.0)
                }
                attributes.transform3D = transfrom
                attributes.zIndex = 1
            }
        }
        
    }
    return array
}
//类似于scrollview的scrollViewWillEndDragging
//proposedContentOffset是没有对齐到网格时本来应该停下的位置
override func targetContentOffsetForProposedContentOffset(proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
    var offsetAdjustment = MAXFLOAT
    //CGRectGetWidth:返回矩形的宽度
    let horizontalCenter = proposedContentOffset.x + (CGRectGetWidth(self.collectionView!.bounds)/2.0)
    //当前rect
    let targetRect = CGRectMake(proposedContentOffset.x
        , 0, self.collectionView!.bounds.size.width, self.collectionView!.bounds.size.height)
    let array = super.layoutAttributesForElementsInRect(targetRect)
    //对当前屏幕中的UIICollectionViewLayoutAttributes 逐个与屏幕中心进行比较,找出最接近中心的一个
    for layoutAttributes in array! {
        let itemHorizontalCenter = layoutAttributes.center.x
        if abs(itemHorizontalCenter - horizontalCenter) < CGFloat(abs(offsetAdjustment)) {
            //与中心的位移差
            offsetAdjustment = Float(itemHorizontalCenter - horizontalCenter)
        }
    }
    //返回修改后停下的位置
    return CGPointMake(proposedContentOffset.x + CGFloat(offsetAdjustment), proposedContentOffset.y)
}

}
原文作者注释的很详细,所以我在swift中也添加了详细的注释。希望对大家有所帮助,( _ )/~~拜拜

你可能感兴趣的:(Swift之用CollectionViewFlowLayout实现LOL皮肤选择动画)