最近看了一篇博文,用collectionView实现了一个很炫的界面,由于那个项目是用OC实现的,所以就想写一个swift分享给大家
参考原文:iOS开发之CollectionViewFlowLayout实现LOL皮肤选择动画
我们先来看一下效果:
由于之前给大家分享过关于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)
}
}