iOS 循環(huán)漸進(jìn)輪播

iOS UICollectionView實(shí)現(xiàn)跑馬燈和輪播效果

功能描述:WSL_RollView 是基于UICollectionView實(shí)現(xiàn)的支持水平和垂直兩個(gè)方向上的的分頁(yè)和漸進(jìn)循環(huán)輪播效果,可以設(shè)置時(shí)間間隔矢否、漸進(jìn)速率饮焦、是否循環(huán)、分頁(yè)寬度和間隔勒虾,還支持自定義分頁(yè)視圖的控件,用法和UICollectionView基本一樣瘸彤。

一修然、實(shí)現(xiàn)方法

①、 首先用UICollectionView和計(jì)時(shí)器實(shí)現(xiàn)一個(gè)基本的水平滾動(dòng)效果质况,如下圖愕宋,這個(gè)太簡(jiǎn)單就不在此詳述。
iOS UICollectionView
②结榄、對(duì)比上面的效果圖中贝,我們還需要解決分頁(yè)的寬度和循環(huán)滾動(dòng)的問題。
  • 自定義分頁(yè)寬度:默認(rèn)的分頁(yè)寬度是UICollectionView的寬度臼朗,所以當(dāng)分頁(yè)寬度的不等于UICollectionView的寬度或分頁(yè)間隔不等于0時(shí)會(huì)出現(xiàn)錯(cuò)誤邻寿,這時(shí)就需要我們通過自定義UICollectionViewFlowLayout來實(shí)現(xiàn)效果。

/** 返回值決定了collectionView停止?jié)L動(dòng)時(shí)的偏移量 手指松開后執(zhí)行
 * proposedContentOffset:原本情況下视哑,collectionView停止?jié)L動(dòng)時(shí)最終的偏移量
 * velocity 滾動(dòng)速率绣否,通過這個(gè)參數(shù)可以了解滾動(dòng)的方向
 */
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity{
    
    if (_scrollStyle == WSLRollViewScrollStylePage) {
        CGSize size = self.collectionView.frame.size;
        // 計(jì)算可見區(qū)域的面積
        CGRect rect = CGRectMake(proposedContentOffset.x, proposedContentOffset.y, size.width, size.height);
        NSArray *array = [super layoutAttributesForElementsInRect:rect];
        // 標(biāo)記 cell 的中點(diǎn)與 UICollectionView 中點(diǎn)最小的間距
        CGFloat minDetal = MAXFLOAT;
        
        if (self.scrollDirection == UICollectionViewScrollDirectionHorizontal){
            // 計(jì)算 CollectionView 中點(diǎn)值
            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{
            // 計(jì)算 CollectionView 中點(diǎn)值
            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;
}

  • 循環(huán)滾動(dòng):思想當(dāng)然還是3 >4 >0 >1 >2 >3 >4 >0 >1,關(guān)鍵就在于怎么確定彌補(bǔ)兩端輪播首尾相連需要增加的cell挡毅,前邊尾首相連需要UICollectionView可見范圍內(nèi)的數(shù)據(jù)源后邊的元素cell蒜撮,后邊首尾相連需要UICollectionView可見范圍內(nèi)的數(shù)據(jù)源前邊的元素cell

//獲取首尾相連循環(huán)滾動(dòng)時(shí)需要用到的元素,并重組數(shù)據(jù)源
- (void)resetDataSourceForLoop{
    if(_loopEnabled == NO){
        return;
    }
    if(_scrollDirection == UICollectionViewScrollDirectionHorizontal && _collectionView.contentSize.width >= self.frame.size.width){
        //用于右側(cè)連接元素?cái)?shù)量
        _addRightCount = [_collectionView  indexPathForItemAtPoint:CGPointMake(self.frame.size.width - 1, 0)].row + 1 ;
        if (_scrollStyle == WSLRollViewScrollStylePage){
            //如果是分頁(yè)跪呈,還需要用于左側(cè)連接元素?cái)?shù)量
            _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){
        //用于右側(cè)連接元素?cái)?shù)量
        _addRightCount = [_collectionView  indexPathForItemAtPoint:CGPointMake(0, self.frame.size.height - 1)].row + 1 ;
        if (_scrollStyle == WSLRollViewScrollStylePage){
            //用于左側(cè)連接元素?cái)?shù)量
            _addLeftCount = _sourceArray.count - [_collectionView  indexPathForItemAtPoint:CGPointMake(0, _collectionView.contentSize.height - self.frame.size.height + 1)].row;
        }
    }
    NSArray * rightSubArray = [_sourceArray subarrayWithRange:NSMakeRange(0, _addRightCount)];
    //增加右側(cè)連接元素
    [_dataSource addObjectsFromArray:rightSubArray];
    
    if (_scrollStyle == WSLRollViewScrollStylePage){
        NSArray * leftSubArray = [_sourceArray subarrayWithRange:NSMakeRange(_sourceArray.count - _addLeftCount, _addLeftCount)];
        //增加左側(cè)連接元素
        [_dataSource insertObjects:leftSubArray atIndexes: [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0,_addLeftCount)]];
    }
}

二段磨、WSL_RollView用法

請(qǐng)看WSLRollView.h文件中的注釋,代理方法庆械、屬性很明朗薇溃,用法和UICollectionView基本一樣,詳情和效果請(qǐng)前往我的Github查看示例:WSL_RollView

//
//  WSLRollView.h
//  WSL_RollView
//
//  Created by 王雙龍 on 2018/9/8.
//  Copyright ? 2018年 http://www.reibang.com/u/e15d1f644bea. All rights reserved.
//

#import <UIKit/UIKit.h>

/**
 默認(rèn)cell樣式 WSLItemID
 */
@interface WSLRollViewCell : UICollectionViewCell
@end

@class WSLRollView;

//代理協(xié)議
@protocol WSLRollViewDelegate <NSObject>
@optional
/**
 返回itemSize 默認(rèn)值是CGSizeMake(self.frame.size.width, self.frame.size.height);
 */
- (CGSize)rollView:(WSLRollView *)rollView sizeForItemAtIndex:(NSInteger)index;
/**
 item的間隔 默認(rèn)值0
 */
- (CGFloat)spaceOfItemInRollView:(WSLRollView *)rollView;
/**
 內(nèi)邊距 上 左 下 右 默認(rèn)值UIEdgeInsetsMake(0, 0, 0, 0)
 */
- (UIEdgeInsets)paddingOfRollView:(WSLRollView *)rollView;
/**
 點(diǎn)擊事件
 */
- (void)rollView:(WSLRollView *)rollView didSelectItemAtIndex:(NSInteger)index;
/**
 自定義item樣式
 */
- (WSLRollViewCell *)rollView:(WSLRollView *)rollView cellForItemAtIndex:(NSInteger )index;
@end

/**
 滾動(dòng)樣式
 */
typedef NS_ENUM(NSInteger, WSLRollViewScrollStyle) {
    WSLRollViewScrollStylePage = 0, /** 分頁(yè) 必須等寬或高*/
    WSLRollViewScrollStyleStep   /** 漸進(jìn) 可以不等寬或高*/
};

@interface WSLRollView : UIView

/**
 原始數(shù)據(jù)源
 */
@property (nonatomic, strong) NSMutableArray * sourceArray;

/**
 是否循環(huán)輪播 默認(rèn)YES
 */
@property (nonatomic, assign) BOOL loopEnabled;

/**
 輪播方向 默認(rèn)是 UICollectionViewScrollDirectionHorizontal 水平
 */
@property (nonatomic, assign) UICollectionViewScrollDirection scrollDirection;

/**
 輪播樣式 默認(rèn)是 WSLRollViewScrollStylePage 分頁(yè)
 */
@property (nonatomic, assign) WSLRollViewScrollStyle scrollStyle;

/**
 漸進(jìn)輪播速率 單位是Point/s缭乘,以坐標(biāo)系單位為準(zhǔn) 默認(rèn)60/s 如果為0 表示禁止計(jì)時(shí)器
 */
@property (nonatomic, assign) CGFloat speed;
/**
 分頁(yè)輪播間隔時(shí)長(zhǎng) 單位是s  默認(rèn)3s 如果為0 表示禁止計(jì)時(shí)器
 */
@property (nonatomic, assign) CGFloat interval;

/**
 item的間隔 默認(rèn)值0
 */
@property (nonatomic, assign) CGFloat spaceOfItem;

/**
 內(nèi)邊距 上 左 下 右 默認(rèn)值UIEdgeInsetsMake(0, 0, 0, 0)
 */
@property (nonatomic, assign) UIEdgeInsets padding;

/** delegate*/
@property (nonatomic, weak) id<WSLRollViewDelegate> delegate;

/**
  初始化方法 direction 滾動(dòng)方向
 */
- (instancetype)initWithFrame:(CGRect)frame scrollDirection:(UICollectionViewScrollDirection)direction;

/**
 注冊(cè)item樣式 用法和UICollectionView相似
 */
- (void)registerClass:(nullable Class)cellClass forCellWithReuseIdentifier:(NSString *)identifier;
/**
 注冊(cè)item樣式 用法和UICollectionView相似
 */
- (void)registerNib:(nullable UINib *)nib forCellWithReuseIdentifier:(NSString *)identifier;
/**
 用于初始化和獲取WSLRollViewCell沐序,自定義cell樣式 用法和UICollectionView相似
 */
- (WSLRollViewCell *)dequeueReusableCellWithReuseIdentifier:(NSString *)identifier forIndex:(NSInteger)index;
/**
 刷新數(shù)據(jù)源
 */
- (void)reloadData;
/**
 暫停自動(dòng)輪播
 */
- (void)pause;
/**
 繼續(xù)自動(dòng)輪播
 */
- (void)play;

@end

以上就是我實(shí)現(xiàn)這個(gè)效果的過程,示例代碼請(qǐng)看這兒WSL_RollView堕绩;如果小伙伴們有其他的實(shí)現(xiàn)方法策幼,歡迎再此留言交流????

推薦閱讀:
iOS UITableView/UICollectionView獲取特定位置的cell
iOS 圖片瀏覽的放大縮小
UIScrollerView當(dāng)前顯示3張圖
iOS 自定義轉(zhuǎn)場(chǎng)動(dòng)畫
iOS 瀑布流封裝
WKWebView的使用
UIScrollView視覺差動(dòng)畫
iOS 傳感器集錦
iOS 音樂播放器之鎖屏歌詞+歌詞解析+鎖屏效果
UIActivityViewController系統(tǒng)原生分享-仿簡(jiǎn)書分享

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市奴紧,隨后出現(xiàn)的幾起案子特姐,更是在濱河造成了極大的恐慌,老刑警劉巖黍氮,帶你破解...
    沈念sama閱讀 218,386評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件唐含,死亡現(xiàn)場(chǎng)離奇詭異浅浮,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)捷枯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門滚秩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人淮捆,你說我怎么就攤上這事郁油。” “怎么了攀痊?”我有些...
    開封第一講書人閱讀 164,704評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵桐腌,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我苟径,道長(zhǎng)案站,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,702評(píng)論 1 294
  • 正文 為了忘掉前任涩笤,我火速辦了婚禮嚼吞,結(jié)果婚禮上盒件,老公的妹妹穿的比我還像新娘蹬碧。我一直安慰自己,他們只是感情好炒刁,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評(píng)論 6 392
  • 文/花漫 我一把揭開白布恩沽。 她就那樣靜靜地躺著,像睡著了一般翔始。 火紅的嫁衣襯著肌膚如雪罗心。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,573評(píng)論 1 305
  • 那天城瞎,我揣著相機(jī)與錄音渤闷,去河邊找鬼。 笑死脖镀,一個(gè)胖子當(dāng)著我的面吹牛飒箭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蜒灰,決...
    沈念sama閱讀 40,314評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼弦蹂,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了强窖?” 一聲冷哼從身側(cè)響起凸椿,我...
    開封第一講書人閱讀 39,230評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎翅溺,沒想到半個(gè)月后脑漫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體髓抑,經(jīng)...
    沈念sama閱讀 45,680評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評(píng)論 3 336
  • 正文 我和宋清朗相戀三年优幸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了启昧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,991評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡劈伴,死狀恐怖密末,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情跛璧,我是刑警寧澤严里,帶...
    沈念sama閱讀 35,706評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站追城,受9級(jí)特大地震影響刹碾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜座柱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評(píng)論 3 330
  • 文/蒙蒙 一迷帜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧色洞,春花似錦戏锹、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至置蜀,卻和暖如春奈搜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背盯荤。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工馋吗, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人秋秤。 一個(gè)月前我還...
    沈念sama閱讀 48,158評(píng)論 3 370
  • 正文 我出身青樓宏粤,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親航缀。 傳聞我的和親對(duì)象是個(gè)殘疾皇子商架,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 1、通過CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫(kù)組件 SD...
    陽(yáng)明先生_X自主閱讀 15,981評(píng)論 3 119
  • 今天把目錄整理了出來芥玉,供大家參考蛇摸。 悄悄說瑪雅歷 目錄 Part1 入門:遇見瑪雅會(huì)幸福 一、13月亮28天歷是什...
    星之奇旅的馮晶晶閱讀 4,061評(píng)論 0 15
  • 說來說去揽涮,創(chuàng)始人沒理想最重要的影響就是沒有圈定一個(gè)功能范圍,對(duì)內(nèi)容型 的產(chǎn)品饿肺,除了功能外還要確定內(nèi)容的邊界蒋困。 我在...
    但我覺得有用閱讀 277評(píng)論 0 0
  • 文/拂曉晚風(fēng) 少了一份記憶 多了一份空白 哆嗦暫時(shí)失去了知覺 夢(mèng)也不曾到訪 就在這個(gè)時(shí)空下 身體狠狠戳痛后依然流浪...
    拂曉晚風(fēng)閱讀 863評(píng)論 12 28