iOS UICollectionView实现卡片效果

    现在使用卡片效果的app很多,之前公司让实现一种卡片效果,就写了一篇关于实现卡片的文章。文章最后附有demo

    实现上我选择了使用UICollectionView ;用UICollectionViewFlowLayout来定制样式;下面看看具体实现

    具体实现

    1、创建UICollectionView

    
     - (void)createCollectionView {
     CGFloat pading = 0 * SCREEN_WIDTH/375;
     LHLeftCollocationView * layout = [[LHLeftCollocationView alloc]init];
     layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
     layout.minimumLineSpacing = pading;
     layout.minimumInteritemSpacing = pading;
    // UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init];
    // layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
     _collectionView3 = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 100, [UIScreen mainScreen].bounds.size.width, imageHeight * SCREEN_RATE) collectionViewLayout:layout];
     _collectionView3.tag = 33;
     _collectionView3.dataSource = self;
     _collectionView3.delegate = self;
     _collectionView3.bounces = NO;
     _collectionView3.alwaysBounceHorizontal = NO;
     _collectionView3.alwaysBounceVertical = NO;
     _collectionView3.backgroundColor = [UIColor grayColor];
     _collectionView3.showsHorizontalScrollIndicator = NO;
     _collectionView3.showsVerticalScrollIndicator = NO;
     [self.view addSubview:_collectionView3];
     [_collectionView3 registerClass:[CollectionViewCell class] forCellWithReuseIdentifier:collectionViewCell];
    }

    2、实现具体代理方法 UICollectionViewDelegate,UICollectionViewDataSource

    
    - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
     return self.modelArray.count;
    }
    
    - (NSMutableArray *)modelArray {
     if (!_modelArray) {
     _modelArray = [NSMutableArray array];
     }
     return _modelArray;
    }
    
    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
     CollModel *infoModel = self.modelArray[indexPath.row];
     NSLog(@"section:%ld --- row:%ld -----%@",indexPath.section,indexPath.row,infoModel.title);
     CollectionViewCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:collectionViewCell forIndexPath:indexPath];
     cell.itemModel = infoModel;
     return cell;
    }
    
    // 返回每个item的大小
    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
     CGFloat CWidth = 80 * SCREEN_RATE;
     CGFloat CHeight = 80 * SCREEN_RATE;
     return CGSizeMake(CWidth, CHeight);
    }
    
    
    #pragma mark - UICollectionViewDelegate点击事件
    - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
     CollModel *infoModel = self.modelArray[indexPath.row];
     NSLog(@"infoModelArray----%@",infoModel.title);
    }

    3、自定义UICollectionViewFlowLayout

    LHLeftCollocationView.m 实现

    
    #import "LHLeftCollocationView.h"
    
    @implementation LHLeftCollocationView
    
    
    - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity {
     CGRect targectRect = CGRectMake(proposedContentOffset.x, 0.0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
     NSArray * attriArray = [super layoutAttributesForElementsInRect:targectRect];
     CGFloat horizontalCenterX = proposedContentOffset.x + ([UIScreen mainScreen].bounds.size.width);
     CGFloat offsetAdjustment = CGFLOAT_MAX;
     for (UICollectionViewLayoutAttributes * layoutAttributes in attriArray) {
     CGFloat itemHorizontalCenterX = layoutAttributes.center.x;
     if (fabs(itemHorizontalCenterX-horizontalCenterX) < fabs(offsetAdjustment)) {
      offsetAdjustment = itemHorizontalCenterX - horizontalCenterX;
     }
     }
     return CGPointMake(proposedContentOffset.x , proposedContentOffset.y);
    }
    
    CGFloat ActiveDistance = 400; //垂直缩放除以系数
    CGFloat ScaleFactor = 0.50; //缩放系数 越大缩放越大
    
    - (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
     NSArray * array = [super layoutAttributesForElementsInRect:rect];
     CGRect visibleRect = CGRectZero;
     visibleRect.origin = self.collectionView.contentOffset;
     visibleRect.size = self.collectionView.bounds.size;
     for (UICollectionViewLayoutAttributes *attributes in array) {
     CGFloat distance = CGRectGetMidX(visibleRect) - attributes.center.x;
     CGFloat normalizedDistance = fabs(distance / ActiveDistance);
     CGFloat zoom = 1 - ScaleFactor * normalizedDistance;
     NSLog(@"zoom----%f",zoom);
     attributes.transform3D = CATransform3DMakeScale(1.0, zoom, 1.0);
     //底部显示效果
     attributes.frame = CGRectMake(attributes.frame.origin.x, attributes.frame.origin.y + zoom, attributes.size.width, attributes.size.height);
     //居中显示效果
    // CGFloat scrollDirectionItemHeight = self.itemSize.height;
    // CGFloat sideItemFixedOffset = 0;
    // sideItemFixedOffset = (scrollDirectionItemHeight - scrollDirectionItemHeight * 0.7) / 2;
    // attributes.center = CGPointMake(attributes.center.x, attributes.center.y + zoom);
    
     }
     return array;
    }
    
    ////设置放大动画
    //-(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
    //{
    // NSArray *arr = [self getCopyOfAttributes:[super layoutAttributesForElementsInRect:rect]];
    // //屏幕中线
    // CGFloat centerX = self.collectionView.contentOffset.x + self.collectionView.bounds.size.width/2.0f;
    // //刷新cell缩放
    // for (UICollectionViewLayoutAttributes *attributes in arr) {
    // CGFloat distance = fabs(attributes.center.x - centerX);
    // //移动的距离和屏幕宽度的的比例
    // CGFloat apartScale = distance/self.collectionView.bounds.size.width;
    // //把卡片移动范围固定到 -π/4到 +π/4这一个范围内
    // CGFloat scale = fabs(cos(apartScale * M_PI/4));
    // //设置cell的缩放 按照余弦函数曲线 越居中越趋近于1
    // attributes.transform = CGAffineTransformMakeScale(1.0, scale);
    // }
    // return arr;
    //}
    
    //防止报错 先复制attributes
    - (NSArray *)getCopyOfAttributes:(NSArray *)attributes
    {
     NSMutableArray *copyArr = [NSMutableArray new];
     for (UICollectionViewLayoutAttributes *attribute in attributes) {
     [copyArr addObject:[attribute copy]];
     }
     return copyArr;
    }
    
    - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
     return true;
    }
    @end

    4、自定义cell 和model

    model

    
    #import <Foundation/Foundation.h>
    
    @interface CollModel : NSObject
    @property (nonatomic,strong)NSString *imgUrl;
    @property (nonatomic,strong)NSString *title;
    @property (nonatomic,strong)NSString *url;
    @end 

    cell 自定义

    
    #import <UIKit/UIKit.h>
    #import "CollModel.h"
    @interface CollectionViewCell : UICollectionViewCell
    @property (nonatomic, strong) CollModel * itemModel;
    
    @end
    
    
    #import "CollectionViewCell.h"
    #define SCREEN_RATE ([UIScreen mainScreen].bounds.size.width/375.0)
    @interface CollectionViewCell()
    /**
     * 存放所有下载操作的队列
     */
    @property (nonatomic, strong) UIImageView *itemIcon;
    @property (nonatomic, strong) UILabel *itemLabel;
    @property (nonatomic, strong) UILabel *priceLabel;
    @end
    
    @implementation CollectionViewCell
    @synthesize itemModel = _itemModel;
    
    - (instancetype)initWithFrame:(CGRect)frame
    {
     if (self = [super initWithFrame:frame]) {
     self.contentView.backgroundColor = [UIColor clearColor];
     [self initView];
     }
     return self;
    }
    
    
    - (void)initView {
     _itemIcon = [[UIImageView alloc] init];
     [self.contentView addSubview:_itemIcon];
     _itemIcon.backgroundColor = [UIColor clearColor];
     // CGFloat iconWidth = ([UIScreen mainScreen].bounds.size.width / 5.0) * SCREEN_RATE;
     _itemIcon.frame = CGRectMake(0, 0, self.contentView.frame.size.width, self.contentView.frame.size.height);
     _itemIcon.center = self.contentView.center;
    }
    
    - (CollModel *)itemModel
    {
     return _itemModel;
    }
    
    - (void)setItemModel:(CollModel *)itemModel
    {
     if (!itemModel) {
     return;
     }
     _itemModel = itemModel;
     [self setCellWithModel:_itemModel];
    }
    
    - (void)setCellWithModel:(CollModel *)itemModel
    {
     [[NSOperationQueue mainQueue] addOperationWithBlock:^{
     _itemIcon.image = [UIImage imageNamed:itemModel.url];
     }];
    }
    @end

    运行效果

    下载demo

    github 下载

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持lingkb。