iOS利用UIScrollView實(shí)現(xiàn)無(wú)限滾動(dòng)效果
前言
眾所周知UIScrollView 的無(wú)限滾動(dòng)主要應(yīng)用在圖片輪播器、歡迎界面等場(chǎng)景。它的原理是在要顯示的圖片前后各加一張圖片即在第一張圖片之前放最后一張圖片,在最后一張圖片之后放第一張圖片,然后在滾動(dòng)到邊緣的時(shí)候,巧妙的過渡一下就可以"瞞天過海","以假亂真"的造成無(wú)限滾動(dòng)的假象。網(wǎng)絡(luò)上有很多只用三張或兩張圖片實(shí)現(xiàn)的方法,效率比這個(gè)方法高,但實(shí)現(xiàn)起來(lái)稍微麻煩一點(diǎn),有興趣的可以去深入研究。
實(shí)現(xiàn)步驟
1、根據(jù)需求準(zhǔn)備幾張圖片,在網(wǎng)上找了5張圖片,分別命名為 img_01,img_02,img_03,img_04,img_05 。
2、代碼實(shí)現(xiàn),主要分為:添加UIScrollView,添加顯示圖片,添加UIPageControl,然后監(jiān)聽UIScrollView的滾動(dòng),根據(jù)滾動(dòng)的位置來(lái)設(shè)置UIPageControl,最重要的是對(duì)于滾動(dòng)到兩個(gè)邊緣時(shí)要特殊處理一下
代碼如下:
#import "ViewController.h"
//屏幕寬度
#define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width
//圖片高度
#define IMG_HEIGHT 180
//要顯示的圖片總數(shù)
#define MAX_SIZE 7
#import "ViewController.h"
@interface ViewController () <UIScrollViewDelegate>
//滾動(dòng)視圖
@property (strong, nonatomic) UIScrollView *loopScrollView;
//指示器
@property (strong, nonatomic) UIPageControl *pageIndicator;
//要展示的圖片數(shù)組
@property(strong, nonatomic) NSMutableArray *imgArray;
@end
@implementation ViewController
//懶加載數(shù)組
-(NSMutableArray *)imgArray
{
if(_imgArray == nil)
{
_imgArray = [[NSMutableArray alloc]initWithCapacity:MAX_SIZE];
//在要展示的5張圖片的前后各加一張圖片,第一張前面加第五張,第五張后面加第一張
[_imgArray addObject:[UIImage imageNamed:@"img_05.jpg"]];
for (int i = 1; i< MAX_SIZE - 1; i++) {
NSString *imgName = [[NSString alloc]initWithFormat:@"img_0%d.jpg", i];
[_imgArray addObject:[UIImage imageNamed:imgName]];
}
[_imgArray addObject:[UIImage imageNamed:@"img_01.jpg"]];
}
return _imgArray;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self setupScrollView];
[self setupPageControl];
}
/**
* 創(chuàng)建UIScrollView并設(shè)置其屬性
*/
-(void)setupScrollView
{
UIScrollView *sc = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 64, SCREEN_WIDTH, IMG_HEIGHT)];
//創(chuàng)建UIImageView并添加到UIScrollView中
for (int i = 0; i< MAX_SIZE; i++) {
UIImageView *img = [[UIImageView alloc]initWithImage:[self.imgArray objectAtIndex:i]];
img.frame = CGRectMake(SCREEN_WIDTH * i, 0, SCREEN_WIDTH, IMG_HEIGHT);
[sc addSubview:img];
}
//設(shè)置UIScrollView的屬性
sc.contentSize = CGSizeMake(SCREEN_WIDTH * self.imgArray.count, IMG_HEIGHT);
sc.showsHorizontalScrollIndicator = NO;
sc.pagingEnabled = YES;
//剛開始應(yīng)該滾動(dòng)到第二張顯示,因?yàn)榈谝粡埰鋵?shí)是最后一張圖片
[sc setContentOffset:CGPointMake(SCREEN_WIDTH, 0) animated:NO];
//設(shè)置代理并添加到當(dāng)前view中
sc.delegate = self;
[self.view addSubview:sc];
self.loopScrollView = sc;
}
/**
* 創(chuàng)建UIPageControl并設(shè)置其屬性
*/
-(void)setupPageControl
{
//注意frame,這樣設(shè)置可以居中顯示
UIPageControl *pc = [[UIPageControl alloc]initWithFrame:CGRectMake(self.view.center.x - 50, CGRectGetMaxY(self.loopScrollView.frame) - 25 , 100, 25)];
//設(shè)置UIPageControl的屬性并添加到當(dāng)前view中
pc.numberOfPages = MAX_SIZE - 2;
pc.currentPage = 0;
pc.pageIndicatorTintColor = [UIColor redColor];
[self.view addSubview:pc];
self.pageIndicator = pc;
}
//UIScrollView的代理方法,在該方法中改變UIPageControl并且處理邊緣滾動(dòng)
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
//獲取當(dāng)前UIScrollView的位置
CGPoint offset = [scrollView contentOffset];
//算出滾動(dòng)到第幾頁(yè)
int currentPage = offset.x/SCREEN_WIDTH;
//設(shè)置UIPageControl
self.pageIndicator.currentPage = currentPage - 1;
//對(duì)最后一張和第一張要進(jìn)行特殊處理
//1、如果是第一張
if (currentPage == 0) {
//下面兩個(gè)方法任選其一都可以達(dá)到效果,但是注意動(dòng)畫一定要設(shè)置為NO,不然會(huì)有視覺會(huì)有辣眼睛的感覺
//方法1
[self.loopScrollView setContentOffset:CGPointMake(SCREEN_WIDTH * (MAX_SIZE-2), 0) animated:NO];
//方法2,該方法要求設(shè)置contentSize時(shí),任一方向就算不滾動(dòng)也不能為0,否則無(wú)效
//[self.loopScrollView scrollRectToVisible:CGRectMake(SCREEN_WIDTH * (MAX_SIZE-2), 0, SCREEN_WIDTH, IMG_HEIGHT) animated:NO];
self.pageIndicator.currentPage = MAX_SIZE - 2;
}
//2、如果是最后一張
else if(currentPage == MAX_SIZE - 1) {
[self.loopScrollView setContentOffset:CGPointMake(SCREEN_WIDTH, 0) animated:NO];
//[self.loopScrollView scrollRectToVisible:CGRectMake(SCREEN_WIDTH, 0, SCREEN_WIDTH, IMG_HEIGHT) animated:NO];
self.pageIndicator.currentPage = 0;
}
}
@end
實(shí)現(xiàn)效果

總結(jié)
好了,以上就是這篇文章的全部?jī)?nèi)容了,其實(shí)實(shí)現(xiàn)輪播現(xiàn)在最好的方案應(yīng)該是使用UICollectionView,因?yàn)樗抢弥赜脵C(jī)制來(lái)實(shí)現(xiàn)的,性能會(huì)好很多,代碼寫起來(lái)類似。希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問大家可以留言交流。
- iOS實(shí)現(xiàn)滾動(dòng)字幕的動(dòng)畫特效
- iOS UIScrollView滾動(dòng)視圖/無(wú)限循環(huán)滾動(dòng)/自動(dòng)滾動(dòng)的實(shí)例代碼
- iOS使用UICollectionView實(shí)現(xiàn)橫向滾動(dòng)照片效果
- IOS中無(wú)限滾動(dòng)Scrollview效果
- iOS實(shí)現(xiàn)無(wú)限循環(huán)滾動(dòng)的TableView實(shí)戰(zhàn)教程
- iOS仿網(wǎng)易新聞滾動(dòng)導(dǎo)航條效果
- iOS實(shí)現(xiàn)類似格瓦拉電影的轉(zhuǎn)場(chǎng)動(dòng)畫
- iOS實(shí)現(xiàn)卡片式滾動(dòng)效果 iOS實(shí)現(xiàn)電影選片效果
相關(guān)文章
iOS tableview實(shí)現(xiàn)簡(jiǎn)單搜索功能
這篇文章主要為大家詳細(xì)介紹了iOS tableview實(shí)現(xiàn)簡(jiǎn)單搜索功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11
iOS 解決UICollectionView 計(jì)算 Cell 大小的問題
本文主要介紹iOS UICollectionView,這里給大家一個(gè)實(shí)例代碼作為參考,并指出經(jīng)常遇到的問題和解決辦法,希望能幫助有需要的小伙伴2016-07-07
ios NSNotificationCenter通知的簡(jiǎn)單使用
這篇文章主要介紹了ios NSNotificationCenter通知的簡(jiǎn)單使用,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2018-06-06
iOS開發(fā)學(xué)習(xí)之監(jiān)測(cè)程序的崩潰次數(shù)詳解
iOS開發(fā)中遇到程序崩潰是很正常的事情,下面這篇文章主要給大家介紹了關(guān)于iOS如何監(jiān)測(cè)程序崩潰次數(shù)的相關(guān)資料,文中通過詳細(xì)的示例代碼供大家參考學(xué)習(xí),需要的朋友們下面跟著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-07-07
iOS開發(fā)APP跳轉(zhuǎn)到設(shè)置或系統(tǒng)頁(yè)面詳解
這篇文章主要為大家介紹了iOS開發(fā)APP跳轉(zhuǎn)到設(shè)置或系統(tǒng)頁(yè)面詳解,<BR>有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06
iOS自定義UITableView實(shí)現(xiàn)不同系統(tǒng)下的左滑刪除功能詳解
關(guān)于左滑刪除這塊,相信不少朋友都遇到過。下面這篇文章主要給大家介紹了關(guān)于iOS如何自定義UITableView實(shí)現(xiàn)不同系統(tǒng)下的左滑刪除功能的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2018-09-09
iOS開發(fā)教程之Status Bar狀態(tài)欄設(shè)置的方法匯總
iOS 的 Status Bar 狀態(tài)欄是一個(gè)比較坑的地方,所以下面這篇文章主要給大家介紹了關(guān)于iOS開發(fā)教程之Status Bar狀態(tài)欄設(shè)置的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2018-08-08
iOS實(shí)現(xiàn)“搖一搖”與“掃一掃”功能示例代碼
本篇文章主要介紹了iOS實(shí)現(xiàn)“搖一搖”與“掃一掃”功能示例代碼,具有一定的參考價(jià)值,有興趣的可以了解一下。2017-01-01

