iOS實(shí)現(xiàn)無(wú)限循環(huán)輪播圖效果
本文實(shí)例為大家分享了iOS實(shí)現(xiàn)無(wú)限循環(huán)輪播圖的具體代碼,供大家參考,具體內(nèi)容如下
輪播圖基礎(chǔ)控件,左滑右滑都能無(wú)限循環(huán)
預(yù)覽
思路
(1)在第一張左邊加一張最后一張的圖片,往左滑到邊緣結(jié)束后計(jì)算偏移量迅速定位成最后一張
#pragma mark - pagecontrol事件 // 這個(gè)是點(diǎn)擊小圓點(diǎn)條進(jìn)行切換,到邊不能循環(huán) - (void)pageControlTouched { // 點(diǎn)擊的時(shí)候停止計(jì)時(shí) [self.kvTimer setFireDate:[NSDate distantFuture]]; // 滑到指定頁(yè)面 NSInteger curPageIdx = _pageControl.currentPage; CGFloat offsetX = self.frame.size.width * (curPageIdx + 1); [self.scrollView setContentOffset:CGPointMake(offsetX, 0) animated:YES]; // 重新開啟定時(shí)器 [self.kvTimer setFireDate:[NSDate dateWithTimeInterval:kTimerInterval sinceDate:[NSDate date]]]; } #pragma mark - 滾動(dòng)事件 - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { // printf("start drag\n"); // 記錄偏移量 preOffsetX = scrollView.contentOffset.x; // 開始手動(dòng)滑動(dòng)時(shí)暫停定時(shí)器 [self.kvTimer setFireDate:[NSDate distantFuture]]; } - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { // printf("end drag\n"); // 左右邊界 CGFloat leftEdgeOffsetX = 0; CGFloat rightEdgeOffsetX = self.frame.size.width * (_pageCount + 1); if (scrollView.contentOffset.x < preOffsetX) { // 左滑 if (scrollView.contentOffset.x > leftEdgeOffsetX) { self.pageControl.currentPage = scrollView.contentOffset.x / self.frame.size.width - 1; } else if (scrollView.contentOffset.x == leftEdgeOffsetX) { self.pageControl.currentPage = _pageCount - 1; } if (scrollView.contentOffset.x == leftEdgeOffsetX) { self.scrollView.contentOffset = CGPointMake(self.frame.size.width * _pageCount, 0); } } else { // 右滑 // 設(shè)置小點(diǎn) if (scrollView.contentOffset.x < rightEdgeOffsetX) { self.pageControl.currentPage = scrollView.contentOffset.x / self.frame.size.width - 1; } else if (scrollView.contentOffset.x == rightEdgeOffsetX) { self.pageControl.currentPage = 0; } // 滑動(dòng)完了之后從最后多余頁(yè)趕緊切換到第一頁(yè) if (scrollView.contentOffset.x == rightEdgeOffsetX) { self.scrollView.contentOffset = CGPointMake(self.frame.size.width, 0); } } // 結(jié)束后又開啟定時(shí)器 [self.kvTimer setFireDate:[NSDate dateWithTimeInterval:kTimerInterval sinceDate:[NSDate date]]]; } - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView { // printf("end scroll\n"); } #pragma mark - 定時(shí)器控制的滑動(dòng) // 往右邊滑 - (void)changePageRight { // 設(shè)置當(dāng)前需要偏移的量,每次遞增一個(gè)page寬度 CGFloat offsetX = _scrollView.contentOffset.x + CGRectGetWidth(self.frame); // 根據(jù)情況進(jìn)行偏移 CGFloat edgeOffsetX = self.frame.size.width * (_pageCount + 1); // 最后一個(gè)多余頁(yè)面右邊緣偏移量 // 從多余頁(yè)往右邊滑,趕緊先設(shè)置為第一頁(yè)的位置 if (offsetX > edgeOffsetX) { // 偏移量,不帶動(dòng)畫,欺騙視覺 self.scrollView.contentOffset = CGPointMake(self.frame.size.width, 0); // 這里提前改變下一個(gè)要滑動(dòng)到的位置為第二頁(yè) offsetX = self.frame.size.width * 2; } // 帶動(dòng)畫滑動(dòng)到下一頁(yè)面 [self.scrollView setContentOffset:CGPointMake(offsetX, 0) animated:YES]; if (offsetX < edgeOffsetX) { self.pageControl.currentPage = offsetX / self.frame.size.width - 1; } else if (offsetX == edgeOffsetX) { // 最后的多余那一頁(yè)滑過(guò)去之后設(shè)置小點(diǎn)為第一個(gè) self.pageControl.currentPage = 0; } } // 往左邊滑 - (void)changePageLeft { // 設(shè)置當(dāng)前需要偏移的量,每次遞減一個(gè)page寬度 CGFloat offsetX = _scrollView.contentOffset.x - CGRectGetWidth(self.frame); // 根據(jù)情況進(jìn)行偏移 CGFloat edgeOffsetX = 0; // 最后一個(gè)多余頁(yè)面左邊緣偏移量 // 從多余頁(yè)往左邊滑動(dòng),先設(shè)置為最后一頁(yè) if (offsetX < edgeOffsetX) { self.scrollView.contentOffset = CGPointMake(self.frame.size.width * _pageCount, 0); offsetX = self.frame.size.width * (_pageCount - 1); } // 帶動(dòng)畫滑動(dòng)到前一頁(yè)面 [self.scrollView setContentOffset:CGPointMake(offsetX, 0) animated:YES]; if (offsetX > edgeOffsetX) { self.pageControl.currentPage = offsetX / self.frame.size.width - 1; } else if (offsetX == edgeOffsetX) { // 最后的多余那一頁(yè)滑過(guò)去之后設(shè)置小點(diǎn)為最后一個(gè) self.pageControl.currentPage = _pageCount - 1; } }
(2)總共只有左、中、右三個(gè)頁(yè)面,每次滑動(dòng)后重新進(jìn)行數(shù)據(jù)跟頁(yè)面的關(guān)聯(lián)
#pragma mark - 定時(shí)器回調(diào) - (void)changePageRight { // 往右滑并且設(shè)置小圓點(diǎn),永遠(yuǎn)都是滑到第三頁(yè) [_scrollView setContentOffset:CGPointMake(self.frame.size.width * 2, 0) animated:YES]; [self resetPageIndex:YES]; } - (void)changePageLeft { // 往左滑,永遠(yuǎn)都是滑動(dòng)到第一頁(yè) [_scrollView setContentOffset:CGPointMake(0, 0) animated:YES]; [self resetPageIndex:NO]; } #pragma mark - 重新設(shè)置索引和頁(yè)面圖片 - (void)resetPageIndex:(BOOL)isRight { if (isRight) { // 根據(jù)之前的page下標(biāo)來(lái)修改 if (_prePageIndex == _pageCount - 1) { // 到頭了就回到第一個(gè) _pageControl.currentPage = 0; } else { // 這里用_prePageIndex來(lái)算,否則點(diǎn)擊小圓點(diǎn)條會(huì)重復(fù)計(jì)算了 _pageControl.currentPage = _prePageIndex + 1; } } else { if (_prePageIndex == 0) { _pageControl.currentPage = _pageCount - 1; } else { _pageControl.currentPage = _prePageIndex - 1; } } _prePageIndex = _pageControl.currentPage; } - (void)resetPageView { // 每次滑動(dòng)完了之后又重新設(shè)置當(dāng)前顯示的page時(shí)中間的page UIImageView *leftPage = [_scrollView viewWithTag:1000]; UIImageView *middlePage = [_scrollView viewWithTag:1001]; UIImageView *rightPage = [_scrollView viewWithTag:1002]; if (_pageControl.currentPage == _pageCount - 1) { // n- 1 -> n -> 0 leftPage.image = _kvImageArray[_pageControl.currentPage - 1]; middlePage.image = _kvImageArray[_pageControl.currentPage]; rightPage.image = _kvImageArray.firstObject; } else if (_pageControl.currentPage == 0) { // n -> 0 -> 1 // 到尾部了,改成從頭開始 leftPage.image = _kvImageArray.lastObject; middlePage.image = _kvImageArray.firstObject; rightPage.image = _kvImageArray[1]; } else { // x - 1 -> x -> x + 1 leftPage.image = _kvImageArray[_pageControl.currentPage - 1]; middlePage.image = _kvImageArray[_pageControl.currentPage]; rightPage.image = _kvImageArray[_pageControl.currentPage + 1]; } // 重新設(shè)置偏移量 _scrollView.contentOffset = CGPointMake(self.frame.size.width, 0); } #pragma mark - pagecontrol事件 - (void)pageControlTouched { [self stopTimer]; NSInteger curPageIndex = _pageControl.currentPage; if (curPageIndex > _prePageIndex) { // 右滑 [self changePageRight]; } else { // 左滑 [self changePageLeft]; } [self startTimer]; } #pragma mark - scrollview滑動(dòng)代理 - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { // 先停掉定時(shí)器 [self stopTimer]; } - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { // 手動(dòng)拖拽滑動(dòng)結(jié)束后 if (scrollView.contentOffset.x > self.frame.size.width) { // 右滑 [self resetPageIndex:YES]; } else { // 左滑 [self resetPageIndex:NO]; } [self resetPageView]; // 開啟定時(shí)器 [self startTimer]; } - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView { // 自動(dòng)滑動(dòng)結(jié)束后重新設(shè)置圖片 [self resetPageView]; }
源代碼下載
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
iOS開發(fā)中WebView的基本使用方法簡(jiǎn)介
這篇文章主要介紹了iOS開發(fā)中WebView的基本使用方法,代碼基于傳統(tǒng)的Objective-C,需要的朋友可以參考下2015-11-11iOS超出父控件范圍無(wú)法點(diǎn)擊問(wèn)題解決
這篇文章主要介紹了iOS超出父控件范圍無(wú)法點(diǎn)擊問(wèn)題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06IOS實(shí)現(xiàn)驗(yàn)證碼倒計(jì)時(shí)功能(二)
這篇文章主要介紹了IOS實(shí)現(xiàn)驗(yàn)證碼倒計(jì)時(shí)功能,點(diǎn)擊獲取驗(yàn)證碼,進(jìn)入時(shí)間倒計(jì)時(shí),感興趣的小伙伴們可以參考一下2016-04-04更新了Xcode8 及 iOS10遇到的問(wèn)題小結(jié)
更新了Xcode8 以及 iOS10,App訪問(wèn)用戶的相機(jī)、相冊(cè)、麥克風(fēng)、通訊錄的權(quán)限都需要重新進(jìn)行相關(guān)的配置,不然在Xcode8中打開編譯的話會(huì)直接crash.這篇文章主要介紹了更新了Xcode8 及 iOS10遇到的問(wèn)題小結(jié)的相關(guān)資料,需要的朋友可以參考下2016-09-09