UICollectionView实现新特性及滑动相册
(一)CollectionViewController:和TableViewController一样,也可以有header和footer。
(二)新特性:一般app的新特性一般也是由CollectionView来实现。其实UIScrollView也可以实现。
回家吃饭APP新特性模拟实现:
主要代码:
self.collectionView?.backgroundColor = UIColor.whiteColor()
self.collectionView!.registerClass(SGCollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier) let layout = collectionViewLayout as! UICollectionViewFlowLayout layout.itemSize = view.bounds.size layout.minimumLineSpacing = 0 layout.scrollDirection = .Horizontal collectionView?.pagingEnabled = false collectionView?.showsHorizontalScrollIndicator = false collectionView?.bounces = false
注意:如上collectionView的属性其实都是UIScrollView的。
大致效果:
(三)实现横向照片相册查看功能
效果图:
实现分析:
(1)此时需要进行更多的设置,需要对layout进行自定义,在preparelayout中进行操作。此方法在一开始布局和刷新布局的时候会进行调用。
(2)在自定义布局中通过计算拿到应该放大的item和缩小的item。改变他们的transform。
(3)刷新item。
主要代码:
// 准备布局和刷新布局的时候调用,在这里进行设置 override func prepareLayout() { // 改变item的size super.prepareLayout() // 设置大小 itemSize = CGSizeMake((collectionView?.frame.size.height)! * 0.6, (collectionView?.frame.size.width)! * 0.6) // 设置滚动方向 scrollDirection = .Horizontal sectionInset = UIEdgeInsetsMake(0, ((collectionView?.frame.size.width)! - itemSize.width) / 2, 0, ((collectionView?.frame.size.width)! - itemSize.width) / 2) }
override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? { // 可以拿到当前 可以看到的cell加上前后cell的各个LayoutAttributes属性 let attrArray = super.layoutAttributesForElementsInRect(rect) // 当前可见cell是两个,一共显示四个 print(attrArray) // 计算屏幕中心点(整个collectionView是横屏移动的,中心点应该等于自己的宽度的一半 + 偏移量) let centerScreen = collectionView!.frame.size.width / 2 + collectionView!.contentOffset.x for arris in attrArray! { // 拿到每个item的中心点 let centerItem = arris.center.x // 计算偏移量的绝对值 let offSet = abs(centerScreen - centerItem) // 通过间隔, 计算一个 放大系数 // (deltaMargin / 250) 计算出一个系数 let scalRatio = 1.2 - (offSet / (self.collectionView!.frame.size.width/2 + arris.size.width)); // 计算transform arris.transform = CGAffineTransformMakeScale(scalRatio, scalRatio) } return attrArray }
// MARK: - 在滚动的时候刷新布局 override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool { return true } // 拖动的时候 ,返回CGPoint,让最中央的图片如果滑动不是太多,就停留在中点 override func targetContentOffsetForProposedContentOffset(proposedContentOffset: CGPoint) -> CGPoint { // 1. 计算屏幕的中心点 let screenCenterX = collectionView!.frame.size.width/2 + proposedContentOffset.x; // 2. 拿到当前的可见rect var visibleRect = CGRectZero; visibleRect.size = collectionView!.frame.size; visibleRect.origin = proposedContentOffset; // 3. 获取可见范围内的cell let attributes = super.layoutAttributesForElementsInRect(visibleRect); // 4. 找到最小距离(屏幕中心点 和 cell 中心点之间的差值) var minMargin = CGFloat(MAXFLOAT); for att in attributes! { // 计算差值 let deltaMargin = att.center.x - screenCenterX ; if (abs(CGFloat(minMargin)) > abs(deltaMargin)) { minMargin = deltaMargin; } } return CGPointMake(proposedContentOffset.x + minMargin, proposedContentOffset.y); }