代碼地址以下:
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大師代發,拒絕轉載,轉載須要做者受權代理