IOS 支付宝-五福简单框架实现-线性滚动(UICollectionView)
猴年支付宝可算是给大家一个很好的惊喜,刺激。大家都在为敬业福而四处奔波。可是到最后也没有几个得到敬业福德,就像我。不知道大家有没有观察,五福界面的滚动是一个很好的设计。在这里,给大家带来简单的滚动实现,首先看一下实现效果。
通过观察不难发现,有很多地方并不是那么容易想出来的,对于篇随笔,感兴趣可以查查相关资料,我就不尽行过多说明,(主要是开考文字,不好说明😄)。
献出代码,请收下。
// // ViewController.m // CX 支付宝-五福简单框架实现-线性滚动(UICollectionView) // // Created by ma c on 16/3/19. // Copyright © 2016年 xubaoaichiyu. All rights reserved. // #import "ViewController.h" #import "CXCollectionViewFlowLayout.h" static NSString * identifier = @"cxCellID"; @interface ViewController ()<UICollectionViewDataSource> @property (nonatomic, strong) UICollectionView * collectionView; @end @implementation ViewController #pragma mark - set_and_get -(UICollectionView *)collectionView{ if (!_collectionView) { //自定义网格布局 CXCollectionViewFlowLayout * flowLayout = [[CXCollectionViewFlowLayout alloc]init]; _collectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 20, self.view.frame.size.width, 300) collectionViewLayout:flowLayout]; _collectionView.dataSource = self; [_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:identifier]; } return _collectionView; } #pragma mark - life - (void)viewDidLoad { [super viewDidLoad]; [self.view addSubview:self.collectionView]; } #pragma mark - deleDate -(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ return 30; } -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ UICollectionViewCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath]; cell.backgroundColor = [UIColor orangeColor]; return cell; } @end
// // CXCollectionViewFlowLayout.m // CX 支付宝-五福简单框架实现-线性滚动(UICollectionView) // // Created by ma c on 16/3/19. // Copyright © 2016年 xubaoaichiyu. All rights reserved. // #import "CXCollectionViewFlowLayout.h" @implementation CXCollectionViewFlowLayout //准备开始布局 -(void)prepareLayout{ [super prepareLayout]; //设置滚动方向 self.scrollDirection = UICollectionViewScrollDirectionHorizontal; //设置item最大size CGFloat width = self.collectionView.frame.size.height * 0.8; self.itemSize = CGSizeMake(width, width); //设置首位Item的位置(通过内边距) CGFloat insertWidth = (self.collectionView.frame.size.width - width) / 2; self.sectionInset = UIEdgeInsetsMake(0, insertWidth, 0, insertWidth); } //返回值为也定cell样式的数组 -(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{ NSArray * attributes = [super layoutAttributesForElementsInRect:rect]; //计算中心点的contentOffset CGFloat centerX = self.collectionView.contentOffset.x + self.collectionView.bounds.size.width * 0.5; //获取每一个cell的布局属性 for (UICollectionViewLayoutAttributes * attri in attributes) { //计算每一个cell中心与中心点的contentOffset距离 CGFloat delat = ABS(attri.center.x - centerX); //计算比例 CGFloat scales = 1 - delat / (self.collectionView.bounds.size.width); attri.transform = CGAffineTransformMakeScale(scales, scales); } return attributes; } //实时刷新 - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { return YES; } //targetContentOffset 调整后的contentOffset //proposedContentOffset 滑动停止的contentOffset - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity { // 计算最终的可见范围 CGRect rect; rect.origin = proposedContentOffset; rect.size = self.collectionView.frame.size; // 取得cell的布局属性 NSArray * attributes = [super layoutAttributesForElementsInRect:rect]; CGFloat centerX = proposedContentOffset.x + self.collectionView.bounds.size.width * 0.5; //获取最小间距 CGFloat minDetal = MAXFLOAT; for (UICollectionViewLayoutAttributes *attrs in attributes) { if (ABS(minDetal) > ABS(attrs.center.x - centerX)) { minDetal = attrs.center.x - centerX; } } // 在原有offset的基础上进行微调 return CGPointMake(proposedContentOffset.x + minDetal, proposedContentOffset.y); } @end