利用UICollectionView實(shí)現(xiàn)無(wú)限循環(huán)輪播圖

之前寫(xiě)的項(xiàng)目堵腹,幾乎每一個(gè)都會(huì)用到循環(huán)輪播圖炸站,于是很早之前就自己寫(xiě)了一個(gè),并一直在使用疚顷。在使用過(guò)程中也會(huì)將出現(xiàn)的BUG進(jìn)行修復(fù)旱易,還會(huì)根據(jù)需求添加一些新的功能,這個(gè)功能就一直修修改改的用著腿堤。今天抽出點(diǎn)時(shí)間咒唆,對(duì)這份代碼進(jìn)行了整理和完善,現(xiàn)在分享出來(lái)供大家一起學(xué)習(xí)释液。
實(shí)現(xiàn)效果,如下圖所示:

效果圖.png

思路與實(shí)現(xiàn)

其實(shí)在明白設(shè)計(jì)思路之后装处,實(shí)現(xiàn)起來(lái)就非常簡(jiǎn)單误债,所以為這里會(huì)先介紹實(shí)現(xiàn)的思路。

思路

我們都知道UICollectionView是系統(tǒng)提供的一個(gè)用于展示各種圖片之類(lèi)的展示的控件妄迁,用UICollectionView展示一組圖片使其可以左右滑動(dòng)寝蹈,包括讓其自動(dòng)滾動(dòng),這些都非常簡(jiǎn)單登淘。但如何讓其實(shí)現(xiàn)無(wú)限循環(huán)滾動(dòng)呢箫老?
其實(shí)原理非常簡(jiǎn)單,就是讓UICollectionView的數(shù)據(jù)源數(shù)組里面多放幾組將要展示的圖片黔州,然后讓UICollectionView滾動(dòng)到中間位置就OK了耍鬓。這里我們需要清楚:數(shù)組中多了那么多圖片阔籽,會(huì)不會(huì)導(dǎo)致內(nèi)存增加呢?其實(shí)牲蜀,這個(gè)完全不用擔(dān)心笆制,因?yàn)閿?shù)組中存放的是圖片的內(nèi)存地址,所以圖片的增加不會(huì)對(duì)內(nèi)存有多大的影響涣达。明白了思路之后在辆,就直接上代碼。

實(shí)現(xiàn)

加載本地圖片

在設(shè)置好輪播圖的位置等一些基本屬性之后度苔,還需要給輪播圖傳一個(gè)圖片數(shù)組addLocalImages:匆篓,具體實(shí)現(xiàn)如下:

- (void)addLocalImages:(NSArray<NSString *> *)images
{
    [ImagesPlayer checkElementOfImages:images];
    [self.dataArray removeAllObjects];
    [self.dataArray addObjectsFromArray:images];
    _images = [NSArray arrayWithArray:self.dataArray];
    
    //刷新pageControl
    self.indicatorView.numberOfPages = images.count;
    [self.indicatorView updateCurrentPageDisplay];
    
    //在Updates里執(zhí)行完更新操作后再執(zhí)行completion回調(diào)
    [self.collectionView performBatchUpdates:^{
        [self.collectionView reloadData];
    } completion:^(BOOL finished) {
        //刷新完成讓collectionView滾動(dòng)到中間位置
        NSInteger center = ceilf([self.collectionView numberOfItemsInSection:0] * 0.5);
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:center inSection:0];
        [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];
        self.previousOffsetX = self.collectionView.contentOffset.x;
        
        //開(kāi)啟定時(shí)器
        [self removeTimer];
        [self addTimer];
    }];
}

這里需要注意的是:每次有新的圖片數(shù)組添加進(jìn)來(lái)時(shí),都需要對(duì)UICollectionView進(jìn)行reloadData才能展示新的圖片寇窑,然后再讓UICollectionView滾動(dòng)到中間位置鸦概,但必須要等到reloadData完成才能滾動(dòng)。所以這里需要用到performBatchUpdates:completion:這個(gè)方法疗认,在updates代碼塊中執(zhí)行對(duì)UICollectionView的更新操作完残,等更新操作完成再調(diào)用completion代碼塊中的代碼。

加載網(wǎng)絡(luò)圖片

因?yàn)樵陧?xiàng)目中輪播圖片是從后臺(tái)獲取的横漏,所以還需要加載網(wǎng)絡(luò)圖片addNetWorkImages:placeholder:谨设。這個(gè)方法與上面加載本地圖片方法相比,就是多了一個(gè)占位圖缎浇,然后利用圖片地址請(qǐng)求網(wǎng)絡(luò)圖片扎拣,請(qǐng)求到圖片后還需做本地緩存,具體實(shí)現(xiàn)如下:

- (void)setImageWithURL:(NSString *)url placeholderImage:(UIImage *)placeholder
{
    NSString *fileDir  = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:@"imagesCache"];
    NSFileManager *fm  = [NSFileManager defaultManager];
    [fm createDirectoryAtPath:fileDir withIntermediateDirectories:YES attributes:nil error:nil];
    NSString *fileName = [fileDir stringByAppendingPathComponent:[self md5:url]];//MD5加密圖片名全路徑
    UIImage *image     = [UIImage imageWithContentsOfFile:fileName];
    if (image) {
        self.image = image;
    }else {
        self.image = placeholder;
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSURL *path = [NSURL URLWithString:url];
            NSData *data = [NSData dataWithContentsOfURL:path];
            dispatch_async(dispatch_get_main_queue(), ^{
                self.image = [UIImage imageWithData:data];
            });
            [data writeToFile:fileName atomically:YES];
        });
    }
}

緩存思路:先從本地取素跺,如果取不到就從網(wǎng)絡(luò)請(qǐng)求二蓝,請(qǐng)求到后存在本地。
因?yàn)樯婕暗奖镜鼐彺嬷秆幔陀星謇砭彺娴男枨罂蓿琧alculateCacheImagesMemory計(jì)算本地緩存的圖片大小,removeCacheMemory清空本地緩存踩验,代碼實(shí)現(xiàn)比較簡(jiǎn)單鸥诽,具體可以在Demo中查看。

分頁(yè)指示器

在項(xiàng)目中因?yàn)轫?xiàng)目UI的要求箕憾,經(jīng)常會(huì)遇到各種不同的分頁(yè)指示器牡借。功能中默認(rèn)的是系統(tǒng)自帶的UIPageControl,也提供了自定義分類(lèi)指示器的接口,使用也很簡(jiǎn)單袭异,只需要先遵守ImagesPlayerIndictorPattern協(xié)議钠龙,并實(shí)現(xiàn)該協(xié)議的方法就行了,具體代碼如下:

- (UIView *)indicatorViewInImagesPlayer:(ImagesPlayer *)imagesPlayer
{
    CGFloat margin          = 5.0;
    UIView *view            = [[UIView alloc] init];
    CGFloat w               = 50;
    CGFloat h               = 20;
    CGFloat x               = CGRectGetWidth(imagesPlayer.frame) - w - margin;
    CGFloat y               = CGRectGetHeight(imagesPlayer.frame) - h - margin;
    view.frame              = CGRectMake(x, y, w, h);
    view.backgroundColor    = [UIColor blackColor];
    view.alpha              = 0.5;
    view.clipsToBounds      = YES;
    view.layer.cornerRadius = 5.0;
    UILabel *lable          = [[UILabel alloc] initWithFrame:view.bounds];
    lable.textAlignment     = NSTextAlignmentCenter;
    lable.textColor         = [UIColor whiteColor];
    self.lable              = lable;
    [view addSubview:lable];
    return view;
}

返回自定義的分頁(yè)指示器的樣式

- (void)imagesPlayer:(ImagesPlayer *)imagesPlayer didChangedIndex:(NSInteger)index count:(NSInteger)count
{
    self.lable.text = [NSString stringWithFormat:@"%ld/%ld", index, count];
}

更新分頁(yè)指示器的顯示

事件處理

這里就對(duì)輪播圖的點(diǎn)擊事件進(jìn)行處理,這里可以通過(guò)代理監(jiān)聽(tīng)或是設(shè)置代碼回調(diào)碴里。
代碼監(jiān)聽(tīng):遵守ImagesPlayerDelegae代理沈矿,實(shí)現(xiàn)imagesPlayer:didSelectImageAtIndex:方法。
代碼回調(diào):通過(guò)imageTapAction:接口設(shè)置回調(diào)代碼塊并闲。
最后需要說(shuō)明的是细睡,在當(dāng)前控制器的viewDidDisappear中要移除定時(shí)器removeTimer,防止沒(méi)必要的CPU消耗帝火。
至此溜徙,整個(gè)輪播圖的基本功能都已實(shí)現(xiàn),大家可以下載Demo犀填,同時(shí)也歡迎大家提出你的想法或意見(jiàn)蠢壹,我們一起相互學(xué)習(xí),共同進(jìn)步>叛病M济场!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末冕广,一起剝皮案震驚了整個(gè)濱河市疏日,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌撒汉,老刑警劉巖沟优,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異睬辐,居然都是意外死亡挠阁,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)溯饵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)侵俗,“玉大人,你說(shuō)我怎么就攤上這事丰刊“ィ” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵啄巧,是天一觀的道長(zhǎng)寻歧。 經(jīng)常有香客問(wèn)我,道長(zhǎng)棵帽,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任渣玲,我火速辦了婚禮逗概,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘忘衍。我一直安慰自己逾苫,他們只是感情好卿城,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著铅搓,像睡著了一般瑟押。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上星掰,一...
    開(kāi)封第一講書(shū)人閱讀 51,737評(píng)論 1 305
  • 那天多望,我揣著相機(jī)與錄音,去河邊找鬼氢烘。 笑死怀偷,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的播玖。 我是一名探鬼主播椎工,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蜀踏!你這毒婦竟也來(lái)了维蒙?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤果覆,失蹤者是張志新(化名)和其女友劉穎颅痊,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體随静,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡八千,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了燎猛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片恋捆。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖重绷,靈堂內(nèi)的尸體忽然破棺而出沸停,到底是詐尸還是另有隱情,我是刑警寧澤昭卓,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布愤钾,位于F島的核電站,受9級(jí)特大地震影響候醒,放射性物質(zhì)發(fā)生泄漏能颁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一倒淫、第九天 我趴在偏房一處隱蔽的房頂上張望伙菊。 院中可真熱鬧,春花似錦、人聲如沸镜硕。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)兴枯。三九已至血淌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間财剖,已是汗流浹背悠夯。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留峰伙,地道東北人疗疟。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像瞳氓,于是被迫代替她去往敵國(guó)和親策彤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

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

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)匣摘、插件店诗、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,107評(píng)論 4 62
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,185評(píng)論 25 707
  • 每個(gè)人身邊都有一個(gè)或者幾個(gè)特別喜歡寫(xiě)作的朋友赠叼,和他們聊天相處擦囊,你總會(huì)不知覺(jué)的成為他們?nèi)蘸蠊P下的素材,也許你的想法和...
    江南少城主閱讀 977評(píng)論 23 23
  • 常量與變量使用let來(lái)聲明常量嘴办,使用var來(lái)聲明變量瞬场。聲明的同時(shí)賦值的話,編譯器會(huì)自動(dòng)推斷類(lèi)型涧郊。值永遠(yuǎn)不會(huì)被隱式轉(zhuǎn)...
    莫_名閱讀 450評(píng)論 0 1
  • 昨夜的風(fēng)是你嗎 染白了門(mén)前的梨花 用思念做養(yǎng)料 在夢(mèng)中開(kāi)出繁華 把春水?dāng)噥y 倒映的是你的臉頰 有種紛亂的情緒 叫做...
    甘棠遺愛(ài)閱讀 247評(píng)論 4 3