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

 

posted @ 2016-03-19 11:04  旭宝爱吃鱼  阅读(2596)  评论(4编辑  收藏  举报