在这里,给大家带来简单的滚动实现,首先看一下实现效果。
通过观察不难发现,有很多地方并不是那么容易想出来的,对于篇随笔,感兴趣可以查查相关资料,我就不尽行过多说明,(主要是开考文字,不好说明😄)。
献出代码,请收下。
#import "ViewController.h"
#import "BYSCollectionViewFlowLayout.h"
static NSString * identifier = @"CellID";
@interface ViewController ()<UICollectionViewDataSource>
@property (nonatomic, strong) UICollectionView * collectionView;
@end
@implementation ViewController
#pragma mark - set_and_get
-(UICollectionView *)collectionView{
if (!_collectionView) {
//自定义网格布局
CXCollectionViewFlowLayout * flowLayout = [[BYSCollectionViewFlowLayout 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
#import "BYSCollectionViewFlowLayout.h"
@implementation BYSCollectionViewFlowLayout
//准备开始布局
-(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