自定义UICollectionViewFlowLayout

1.自定义一个继承自UICollectionViewFlowLayout的类

//
//  LineLayout.h
//  自定义UICellectionView布局
//


#import <UIKit/UIKit.h>

@interface LineLayout : UICollectionViewFlowLayout

@end

//
//  LineLayout.m
//  自定义UICellectionView布局
//


#import "LineLayout.h"

static const CGFloat ItemWH = 100;

@implementation LineLayout




/**
 *  只要显示的边界发生改变就重新布局
 *  内部就会重新调用layoutAttributesForElementsInRect方法获得cell布局属性
 */
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
    return YES;
}

/**
 *  用来设置CollectionView停止滚动那一刻的位置(系统自动调用)
 *
 *  @param proposedContentOffset 原本scrollView停止滚动那一刻的位置
 *  @param velocity              滚动速度
 */
 - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
    //1.计算出CollectionView最后停留的范围
    CGRect lastRect;
    lastRect.origin = proposedContentOffset;
    lastRect.size =  self.collectionView.frame.size;
    
    //2.计算屏幕最中间的x
    CGFloat centerX = proposedContentOffset.x + self.collectionView.frame.size.width;

    //3.取出这个范围内的所有属性
    NSArray *array = [self layoutAttributesForElementsInRect:lastRect];
    
    //4.遍历所有属性
    CGFloat adjustOffsetX = MAXFLOAT;
    for (UICollectionViewLayoutAttributes *attrs in array) {
        if (ABS(attrs.center.x - centerX) < ABS(adjustOffsetX)) {
            adjustOffsetX = attrs.center.x - centerX;
        }
    }
    
    return CGPointMake(proposedContentOffset.x + adjustOffsetX, proposedContentOffset.y);
}

/**
 *  一些初始化的工作最好在这里做
 */
- (void)prepareLayout
{
    [super prepareLayout];
    //每个cell的尺寸
    self.itemSize = CGSizeMake(ItemWH, ItemWH);
    CGFloat inset = (self.collectionView.frame.size.width - ItemWH) * 0.5;
    self.sectionInset = UIEdgeInsetsMake(0, inset, 0, inset);
    //设置水平滚动方向
    self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    //设置cell的间距(行距)
    self.minimumInteritemSpacing = 100;
}

- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
    //0.计算可见的矩形框
    CGRect visiableRect;
    visiableRect.size = self.collectionView.frame.size;
    visiableRect.origin = self.collectionView.contentOffset;
    
    //1.取得默认的cell的UICollectionViewLayoutAttributes
    NSArray *array = [super layoutAttributesForElementsInRect:rect];
    
    //2.计算屏幕最中间的x
    CGFloat centerX = self.collectionView.contentOffset.x + self.collectionView.frame.size.width * 0.5;
    
    //3.遍历所有属性
    for (UICollectionViewLayoutAttributes *attrs in array) {
        if (!CGRectIntersectsRect(visiableRect, attrs.frame)) continue;
        
        //每一个item的中点x
        CGFloat itemCenterX = attrs.center.x;
        
        //根据屏幕最中间的距离计算缩放比例
        CGFloat scale = 1 + 0.7 * (1 - ABS(itemCenterX - centerX) / self.collectionView.frame.size.width);
        attrs.transform3D = CATransform3DMakeScale(scale, scale, 1.0);
    }
    
    
    return array;
}

@end
2.控制器里创建UICollectionView
//
//  ViewController.m
//  自定义UICellectionView布局
//


#import "ViewController.h"
#import "ImageCell.h"
#import "LineLayout.h"

@interface ViewController () <UICollectionViewDataSource,UICollectionViewDelegate>
@property(nonatomic,strong)NSMutableArray *images;
@property(nonatomic,weak)UICollectionView *collectionView;
@end

@implementation ViewController

static NSString *const ID = @"image";

- (NSMutableArray *)images
{
    if (!_images) {
        self.images = [[NSMutableArray alloc] init];
        for (int i=1; i<=20; i++) {
            [self.images addObject:[NSString stringWithFormat:@"%d",i]];
        }
    }
    return _images;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //1.创建一个UICollectionView并添加到视图
    CGFloat w = self.view.frame.size.width;
    CGRect rect = CGRectMake(0, 100, w, 200);
    
    UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:rect collectionViewLayout:[[LineLayout alloc] init]];
    collectionView.backgroundColor = [UIColor orangeColor];
    collectionView.delegate = self;
    collectionView.dataSource = self;
    [collectionView registerNib:[UINib nibWithNibName:@"ImageCell" bundle:nil] forCellWithReuseIdentifier:ID];
    [self.view addSubview:collectionView];
    self.collectionView = collectionView;
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    //改布局
    if ([self.collectionView.collectionViewLayout isKindOfClass:[LineLayout class]]) {
        [self.collectionView setCollectionViewLayout:[[UICollectionViewFlowLayout alloc] init] animated:YES];
    }else{
         [self.collectionView setCollectionViewLayout:[[LineLayout alloc] init] animated:YES];
    }
}

#pragma mark - UICollectionViewDataSource
/**
 *  每组有多少个cell
 */
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return self.images.count;
}

/**
 *  返回cell

 */
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    ImageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath];
    cell.image = self.images[indexPath.item];
    return cell;
}

#pragma mark - UICollectionViewDelegate
/**
 *  点击了cell
 */
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    //删掉一个cell
    
    //1.删除模型数据
    [self.images removeObjectAtIndex:indexPath.item];
    //2.刷新UI
    [collectionView deleteItemsAtIndexPaths:@[indexPath]];
    
}

@end
3.用到的自定义的UICollectionViewCell
//
//  ImageCell.h
//  自定义UICellectionView布局


#import <UIKit/UIKit.h>

@interface ImageCell : UICollectionViewCell
@property(nonatomic,copy)NSString *image;
@end

//
//  ImageCell.m
//  自定义UICellectionView布局


#import "ImageCell.h"

@interface ImageCell()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end

@implementation ImageCell

- (void)awakeFromNib
{
    self.imageView.layer.borderColor = [UIColor whiteColor].CGColor;
    self.imageView.layer.borderWidth = 2;
    self.imageView.layer.masksToBounds = YES;
    self.imageView.layer.cornerRadius = 5;
    
}

- (void)setImage:(NSString *)image
{
    _image = [image copy];
    
    self.imageView.image = [UIImage imageNamed:image];
}

@end
4.ImageCell.xib


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值