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)<CGFloat(ACTIVE_DISTANCE)  {
                //normalizedDistance 当前位移比上完成一个过程所需位移 得到不完全过程的旋转角度
                let zoom = CGFloat(ROTATE) * normalizedDistance
                var transfrom = CATransform3DIdentity
                transfrom.m34 = 1.0/600
                transfrom = CATransform3DRotate(transfrom, -zoom, 0.0, 1.0, 0.0)
                attributes.transform3D = transfrom
                attributes.zIndex = 1
            }else {
                var transfrom = CATransform3DIdentity
                transfrom.m34 = 1.0 / 600
                //向右滑
                if (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中也添加了详细的注释。希望对大家有所帮助,( _ )/~~拜拜
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,012评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,589评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,819评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,652评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,954评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,381评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,687评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,404评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,082评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,355评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,880评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,249评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,864评论 3 232
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,007评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,760评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,394评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,281评论 2 259

推荐阅读更多精彩内容