代码地址以下:
http://www.demodashi.com/demo/14075.htmlhtml
功能描述:WSL_RollView 是基于UICollectionView实现的支持水平和垂直两个方向上的的分页和渐进循环轮播效果,能够设置时间间隔、渐进速率、是否循环、分页宽度和间隔,还支持高度自定义分页视图的控件。ide
/** 返回值决定了collectionView中止滚动时的偏移量 手指松开后执行 * proposedContentOffset:本来状况下,collectionView中止滚动时最终的偏移量 * velocity 滚动速率,经过这个参数能够了解滚动的方向 */ - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity{ if (_scrollStyle == WSLRollViewScrollStylePage) { CGSize size = self.collectionView.frame.size; // 计算可见区域的面积 CGRect rect = CGRectMake(proposedContentOffset.x, proposedContentOffset.y, size.width, size.height); NSArray *array = [super layoutAttributesForElementsInRect:rect]; // 标记 cell 的中点与 UICollectionView 中点最小的间距 CGFloat minDetal = MAXFLOAT; if (self.scrollDirection == UICollectionViewScrollDirectionHorizontal){ // 计算 CollectionView 中点值 CGFloat centerX = proposedContentOffset.x + self.collectionView.frame.size.width * 0.5; for (UICollectionViewLayoutAttributes *attrs in array){ if (ABS(minDetal) > ABS(centerX - attrs.center.x)){ minDetal = attrs.center.x - centerX; } } return CGPointMake(proposedContentOffset.x + minDetal, proposedContentOffset.y); }else{ // 计算 CollectionView 中点值 CGFloat centerY = proposedContentOffset.y + self.collectionView.frame.size.height * 0.5; for (UICollectionViewLayoutAttributes *attrs in array){ if (ABS(minDetal) > ABS(centerY - attrs.center.y)){ minDetal = attrs.center.y - centerY; } } return CGPointMake(proposedContentOffset.x, proposedContentOffset.y + minDetal); } } return proposedContentOffset; }
//获取首尾相连循环滚动时须要用到的元素,并重组数据源 - (void)resetDataSourceForLoop{ if(_loopEnabled == NO){ return; } if(_scrollDirection == UICollectionViewScrollDirectionHorizontal && _collectionView.contentSize.width >= self.frame.size.width){ //用于右侧链接元素数量 _addRightCount = [_collectionView indexPathForItemAtPoint:CGPointMake(self.frame.size.width - 1, 0)].row + 1 ; if (_scrollStyle == WSLRollViewScrollStylePage){ //若是是分页,还须要用于左侧链接元素数量 _addLeftCount = _sourceArray.count - [_collectionView indexPathForItemAtPoint:CGPointMake(_collectionView.contentSize.width - self.frame.size.width + 1, 0)].row; } }else if(_scrollDirection == UICollectionViewScrollDirectionVertical && _collectionView.contentSize.height >= self.frame.size.height){ //用于右侧链接元素数量 _addRightCount = [_collectionView indexPathForItemAtPoint:CGPointMake(0, self.frame.size.height - 1)].row + 1 ; if (_scrollStyle == WSLRollViewScrollStylePage){ //用于左侧链接元素数量 _addLeftCount = _sourceArray.count - [_collectionView indexPathForItemAtPoint:CGPointMake(0, _collectionView.contentSize.height - self.frame.size.height + 1)].row; } } NSArray * rightSubArray = [_sourceArray subarrayWithRange:NSMakeRange(0, _addRightCount)]; //增长右侧链接元素 [_dataSource addObjectsFromArray:rightSubArray]; if (_scrollStyle == WSLRollViewScrollStylePage){ NSArray * leftSubArray = [_sourceArray subarrayWithRange:NSMakeRange(_sourceArray.count - _addLeftCount, _addLeftCount)]; //增长左侧链接元素 [_dataSource insertObjects:leftSubArray atIndexes: [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0,_addLeftCount)]]; } }
请看WSLRollView.h文件中的注释,属性和用法很明朗,详情和效果能够看代码。oop
// // WSLRollView.h // WSL_RollView // // Created by 王双龙 on 2018/9/8. // Copyright © 2018年 https://www.jianshu.com/u/e15d1f644bea. All rights reserved. // #import <UIKit/UIKit.h> /** 默认cell样式 WSLItemID */ @interface WSLRollViewCell : UICollectionViewCell @end @class WSLRollView; //代理协议 @protocol WSLRollViewDelegate <NSObject> @optional /** 返回itemSize 默认值是CGSizeMake(self.frame.size.width, self.frame.size.height); */ - (CGSize)rollView:(WSLRollView *)rollView sizeForItemAtIndex:(NSInteger)index; /** item的间隔 默认值0 */ - (CGFloat)spaceOfItemInRollView:(WSLRollView *)rollView; /** 内边距 上 左 下 右 默认值UIEdgeInsetsMake(0, 0, 0, 0) */ - (UIEdgeInsets)paddingOfRollView:(WSLRollView *)rollView; /** 点击事件 */ - (void)rollView:(WSLRollView *)rollView didSelectItemAtIndex:(NSInteger)index; /** 自定义item样式 */ - (WSLRollViewCell *)rollView:(WSLRollView *)rollView cellForItemAtIndex:(NSInteger )index; @end /** 滚动样式 */ typedef NS_ENUM(NSInteger, WSLRollViewScrollStyle) { WSLRollViewScrollStylePage = 0, /** 分页 必须等宽或高*/ WSLRollViewScrollStyleStep /** 渐进 能够不等宽或高*/ }; @interface WSLRollView : UIView /** 原始数据源 */ @property (nonatomic, strong) NSMutableArray * sourceArray; /** 是否循环轮播 默认YES */ @property (nonatomic, assign) BOOL loopEnabled; /** 轮播方向 默认是 UICollectionViewScrollDirectionHorizontal 水平 */ @property (nonatomic, assign) UICollectionViewScrollDirection scrollDirection; /** 轮播样式 默认是 WSLRollViewScrollStylePage 分页 */ @property (nonatomic, assign) WSLRollViewScrollStyle scrollStyle; /** 渐进轮播速率 单位是Point/s,以坐标系单位为准 默认60/s 若是为0 表示禁止计时器 */ @property (nonatomic, assign) CGFloat speed; /** 分页轮播间隔时长 单位是s 默认3s 若是为0 表示禁止计时器 */ @property (nonatomic, assign) CGFloat interval; /** item的间隔 默认值0 */ @property (nonatomic, assign) CGFloat spaceOfItem; /** 内边距 上 左 下 右 默认值UIEdgeInsetsMake(0, 0, 0, 0) */ @property (nonatomic, assign) UIEdgeInsets padding; /** delegate*/ @property (nonatomic, weak) id<WSLRollViewDelegate> delegate; /** 初始化方法 direction 滚动方向 */ - (instancetype)initWithFrame:(CGRect)frame scrollDirection:(UICollectionViewScrollDirection)direction; /** 注册item样式 用法和UICollectionView类似 */ - (void)registerClass:(nullable Class)cellClass forCellWithReuseIdentifier:(NSString *)identifier; /** 注册item样式 用法和UICollectionView类似 */ - (void)registerNib:(nullable UINib *)nib forCellWithReuseIdentifier:(NSString *)identifier; /** 用于初始化和获取WSLRollViewCell,自定义cell样式 用法和UICollectionView类似 */ - (WSLRollViewCell *)dequeueReusableCellWithReuseIdentifier:(NSString *)identifier forIndex:(NSInteger)index; /** 刷新数据源 */ - (void)reloadData; /** 暂停自动轮播 */ - (void)pause; /** 继续自动轮播 */ - (void)play; /** 释放计时器 必须执行,防止内存暴涨 */ - (void)close; @end
以上就是我实现这个效果的过程;若是小伙伴们有其余的实现方法,欢迎再此留言交流😊😊😀😀🤗🤗ui
iOS 封装跑马灯和轮播效果atom
代码地址以下:
http://www.demodashi.com/demo/14075.htmlspa
注:本文著做权归做者,由demo大师代发,拒绝转载,转载须要做者受权代理