IOS知识积累

IOS UICollectionView的使用以及Flowla

2019-09-29  本文已影响0人  越天高

UICollectionView使用注意点

1.创建UICollectionView必须要有布局参数
2.cell必须通过注册
3.cell必须自定义,系统cell没有任何子控件

  UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
    layout.itemSize = CGSizeMake(160, 160);//每一个cell的大小
    layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;//滚动方向
    CGFloat margin = (SCREEN_WIDTH - 160) *0.5;
    layout.sectionInset = UIEdgeInsetsMake(0, margin, 0, margin);//四周的边距
    //设置最小边距
    layout.minimumLineSpacing = 50;


    
    //创建UICollectionView
    UICollectionView *collectionV = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 200, SCREEN_WIDTH, 200) collectionViewLayout:layout];
    collectionV.backgroundColor = [UIColor brownColor];
    collectionV.dataSource = self;
    [collectionV registerNib:[UINib nibWithNibName:@"PhotoCell" bundle:nil] forCellWithReuseIdentifier:cellID];
    [self.view addSubview:collectionV];

#pragma mark - CollectionViewDelegate -

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return 10;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    PhotoCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellID forIndexPath:indexPath];
    NSString *imageName = [NSString stringWithFormat:@"%ld", indexPath.row + 1];
    
    cell.image = [UIImage imageNamed:imageName];
    return cell;
}

自定义Layout实现动态的改变效果,很多卡片效果都可以借助这种方式实现

/*********ViewControlle.m*************/
#import "ViewController.h"
#import "PhotoCell.h"
#import "FlowLayout.h"

#define SCREEN_WIDTH    ([UIScreen mainScreen].bounds.size.width)
#define SCREEN_HEIGHT   ([UIScreen mainScreen].bounds.size.height)

@interface ViewController ()<UICollectionViewDataSource>
@property (nonatomic, weak)  UICollectionView *collectionView;

@end

static NSString *const cellID = @"photoCellID";
@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // UICollectionView使用注意点
    // 1.创建UICollectionView必须要有布局参数
    // 2.cell必须通过注册
    // 3.cell必须自定义,系统cell没有任何子控件
    
    // 流水布局:调整cell尺寸
    FlowLayout *layout = ({
        
        FlowLayout *layout = [[FlowLayout alloc] init];
        layout.itemSize = CGSizeMake(160, 160);//每一个cell的大小
        layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;//滚动方向
        CGFloat margin = (SCREEN_WIDTH - 160) *0.5;
        layout.sectionInset = UIEdgeInsetsMake(0, margin, 0, margin);//四周的边距
        //设置最小边距
        layout.minimumLineSpacing = 50;
        
        layout;
    });
    
    // 创建UICollectionView
    // 函数式编程思想(高聚合):把很多功能放在一个函数块(block块)去处理
    // 编程思想:低耦合,高聚合(代码聚合,方便去管理)
    
    UICollectionView *collectionV = ({
        
        UICollectionView *collectionV = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 200, SCREEN_WIDTH, 200) collectionViewLayout:layout];
        collectionV.backgroundColor = [UIColor brownColor];
        collectionV.dataSource = self;
       
        [self.view addSubview:collectionV];
        collectionV;
    });
    self.collectionView = collectionV;
     [collectionV registerNib:[UINib nibWithNibName:@"PhotoCell" bundle:nil] forCellWithReuseIdentifier:cellID];
   
}


- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [self.collectionView reloadData];

}


- (void)reloadMyCollectionView
{
    [self.collectionView reloadData];
}


#pragma mark - CollectionViewDelegate -

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return 10;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    PhotoCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellID forIndexPath:indexPath];
    NSString *imageName = [NSString stringWithFormat:@"%ld", indexPath.row + 1];
    
    cell.image = [UIImage imageNamed:imageName];
    return cell;
}
@end

/*********FlowLayout.m*************/

#import "FlowLayout.h"

@implementation FlowLayout

/*
 自定义布局:只要了解5个方法
 
 - (void)prepareLayout;
 
 - (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect;
 
 - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds;
 
 - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity; // return a point at which to rest after scrolling - for layouts that want snap-to-point scrolling behavior
 
 - (CGSize)collectionViewContentSize;
 
 */


/*
UICollectionViewLayoutAttributes:确定cell的尺寸
一个UICollectionViewLayoutAttributes对象就对应一个cell
拿到UICollectionViewLayoutAttributes相当于拿到cell
*/

// 重写它方法,扩展功能

// 什么时候调用:collectionView第一次布局,collectionView刷新的时候也会调用
// 作用:计算cell的布局,条件:cell的位置是固定不变

- (void)prepareLayout
{
    [super prepareLayout];
   // NSLog(@"prepareLayout");
}

// 作用:指定一段区域给你这段区域内cell的尺寸
// 可以一次性返回所有cell尺寸,也可以每隔一个距离返回cell
- (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{// 设置cell尺寸 => UICollectionViewLayoutAttributes
    // 越靠近中心点,距离越小,缩放越大
    // 求cell与中心点距离
    
    // 1.获取当前显示cell的布局
    NSArray *attrs = [super layoutAttributesForElementsInRect:self.collectionView.bounds];
    
    for (UICollectionViewLayoutAttributes *attr in attrs) {

        //2计算到中心的距离
        CGFloat dinstance = fabs((attr.center.x - self.collectionView.contentOffset.x) - self.collectionView.bounds.size.width * 0.5);
        //3.计算比例
        CGFloat scale = 1 -  dinstance / (self.collectionView.bounds.size.width * 0.5 ) * 0.25;
        attr.transform = CGAffineTransformMakeScale(scale, scale);

    }
    return attrs;
}


// 什么时候调用:用户手指一松开就会调用
// 作用:确定最终偏移量
// 定位:距离中心点越近,这个cell最终展示到中心点

- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
    // 拖动比较快 最终偏移量 不等于 手指离开时偏移量
    CGFloat collectionW = self.collectionView.bounds.size.width;

    // 最终偏移量
    CGPoint targetP = [super targetContentOffsetForProposedContentOffset:proposedContentOffset withScrollingVelocity:velocity];
    // 0.获取最终显示的区域
    CGRect targetRect = CGRectMake(targetP.x, 0, collectionW, MAXFLOAT);
    // 1.获取最终显示的cell
    NSArray *attrs = [super layoutAttributesForElementsInRect:targetRect];
    
    // 计算获取最小间距
    CGFloat minDelta = MAXFLOAT;
    
    for (UICollectionViewLayoutAttributes *attr in attrs)
    {
        CGFloat distance = attr.center.x - targetP.x - self.collectionView.bounds.size.width * 0.5;
        if (fabs(distance) < fabs(minDelta)) {
            minDelta = distance ;
        }
    }
    //移动距离
    targetP.x += minDelta;
    
    if (targetP.x < 0) {
        targetP.x = 0;
    }
  
    return targetP;
}

// Invalidate:刷新
// 在滚动的时候是否允许刷新布局
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{
    return YES;
}
// 计算collectionView滚动范围

- (CGSize)collectionViewContentSize
{
    return [super collectionViewContentSize];
}
@end

上一篇下一篇

猜你喜欢

热点阅读