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
网友评论