iOS簡單實現(xiàn)輪播圖效果
本文實例為大家分享了iOS簡單實現(xiàn)輪播圖效果的具體代碼,供大家參考,具體內(nèi)容如下
平常在開發(fā)過程中,首頁的輪播圖總是少不了,輪播圖我們都知道肯定是要使用 UIScrollView ,難點就在最后一張圖片被滑動時,如何回到第一張圖片以及第一張滑動到最后一張。
我們可以使用如下方式實現(xiàn)輪播圖,在劃到3后面的1后,設(shè)置 contentOffset 回到最先的1,并設(shè)置 pageControl ,即可達到效果 (從1劃到3也同理)
看一下效果:
完成這種輪播圖,我們的 View 需要如下的屬性和方法
@interface RoundView : UIView ? @property (nonatomic,strong) UIScrollView ? *scrollView; //存放ScrollView每一個page的圖片的array @property (nonatomic) NSMutableArray ? ? ? ?*imgArray; @property (nonatomic) UIPageControl ? ? ? ? *pageControl; //定時器 @property (nonatomic,strong) NSTimer ? ? ? ?*__nullable timer; ? - (instancetype)initWithFrame:(CGRect)frame imgArray:(NSArray *)array; ? @end
在創(chuàng)建View的時候使用 initWithFrame:(CGRect)frame imgArray:(NSArray *)array,傳入需要展示的 imgArray ,在 view 內(nèi)進行處理。
在該方法的實現(xiàn)中,首先就是對圖片數(shù)組array的處理,得到我們需要的imgArray
- (instancetype)initWithFrame:(CGRect)frame imgArray:(NSArray *)array{ ? ? self=[super initWithFrame:frame]; ? ?? ? ? self.imgArray=[[NSMutableArray alloc]init]; ? ? [self.imgArray addObject:[array lastObject]]; ? ? [self.imgArray addObjectsFromArray:array]; ? ? [self.imgArray addObject:[array firstObject]]; }
這樣,我們的 imgArray 就變成了最開始演示原理的樣式,為 @[first object,array,lastobject]
然后我們初始化一下 ScrollView
self.scrollView=[[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)]; ? ? [self.scrollView.layer setCornerRadius:10.0]; ? ? self.scrollView.contentSize=CGSizeMake(frame.size.width * self.imgArray.count, frame.size.height); ? ? self.scrollView.pagingEnabled=YES; ? ? self.scrollView.contentOffset=CGPointMake(frame.size.width, 0); ? ? self.scrollView.showsVerticalScrollIndicator=NO; ? ? self.scrollView.showsHorizontalScrollIndicator=NO; ? ? self.scrollView.delegate=self; ? ? [self.scrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
很簡單,就是一些屬性、代理的設(shè)置 根據(jù) imgArray 的大小設(shè)置 contentSize ,另外對 contentOffset 添加一個觀察者,方便后續(xù)對pageControl和contentOffset進行設(shè)置。
然后,我們根據(jù) imgArray 將圖片填入到 scrollView 中
for(int i=0;i<self.imgArray.count;i++){ ? ? ? ? CGRect imgFrame=CGRectMake(frame.size.width* i, 0, frame.size.width , frame.size.height); ? ? ? ? UIImageView* imgView=[[UIImageView alloc]initWithFrame:imgFrame]; ? ? ? ? //這里我就不傳入圖片了,測試的imgArray中為顏色,使用顏色替代 ? ? ? ? imgView.backgroundColor=self.imgArray[i]; ? ? ? ? [self.scrollView addSubview:imgView]; ? ? }
然后對pageControl和timer進行初始化
self.pageControl=[[UIPageControl alloc]initWithFrame:CGRectMake(0, frame.size.height-20, frame.size.width, 20)]; ? ? self.pageControl.numberOfPages=array.count; ? ? self.pageControl.currentPage=0; ? ? self.pageControl.tintColor=[UIColor whiteColor]; ? ?? ? ? self.timer=[NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(scrollImage) userInfo:nil repeats:YES]; ? ? //添加到runloop中 ? ? NSRunLoop *runloop=[NSRunLoop currentRunLoop]; ? ? [runloop addTimer:self.timer forMode:NSRunLoopCommonModes]; ? ?? ? ? [self addSubview:self.scrollView]; ? ? [self addSubview:self.pageControl];
這里設(shè)置的是5秒鐘后自動滾動輪播圖,可以根據(jù)需要自己設(shè)置,scrollmage 方法后面會講
我們看一下我們需要的 scrollView 的代理方法
1.scrollViewDidScroll:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{ ? ? CGFloat offsetX=scrollView.contentOffset.x; ? ? offsetX+=scrollView.frame.size.width*0.5; ? ?? ? ? //因為最前面還有一個imgView ? ? int page=offsetX/scrollView.frame.size.width-1; ? ? self.pageControl.currentPage=page; ? ?? }
此方法用來計算 contentOffset 對應(yīng)的 pageControl 的 page ,需要注意的是在第一張圖片之前還有最后一張圖片,所以計算的時候需要-1
2.scrollViewWillBgeinDragging:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{ ? ? [self.timer invalidate]; ? ? self.timer=nil; }
在scrollView即將被劃動時,取消自動輪播,將timer設(shè)置為nil
3.scorllViewDidEndDragging: willDecelearate:
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{ ? ? self.timer=[NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(scrollImage) userInfo:nil repeats:YES]; ? ?? ? ? //優(yōu)先級 設(shè)置到當(dāng)前的runloop中 ? ? NSRunLoop *runloop=[NSRunLoop currentRunLoop]; ? ? [runloop addTimer:self.timer forMode:NSRunLoopCommonModes]; }
在將要結(jié)束劃動的時候,重新設(shè)置timer 并添加到當(dāng)前的runloop中
實現(xiàn)輪播圖的核心代碼
對 contentOffset 的監(jiān)聽
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{ ? ?? ? ? if([keyPath isEqualToString:@"contentOffset"]){ ? ? ? ? //[change objectForKey:NSKeyValueChangeNewKey] 是一個對象 ? ? ? ? CGPoint offset= [[change objectForKey:NSKeyValueChangeNewKey] CGPointValue]; ? ? ? ? //當(dāng)劃到3后面的1時 ? ? ? ? if(offset.x >= self.scrollView.contentSize.width-self.scrollView.frame.size.width){ ? ? ? ? ? ? [self.scrollView setContentOffset:CGPointMake(self.scrollView.frame.size.width, 0)]; ? ? ? ? ? ? self.pageControl.currentPage=0; ? ? ? ? } ? ? ? ? //當(dāng)劃到1前面的3時 ? ? ? ? else if(offset.x <= 0){ ? ? ? ? ? ? [self.scrollView setContentOffset:CGPointMake(self.scrollView.contentSize.width-2*self.scrollView.frame.size.width, 0)]; ? ? ? ? ? ? self.pageControl.currentPage=self.pageControl.numberOfPages-1; ? ? ? ? } ? ? } ? ?? }
首先[change objectForKey:NSKeyValueChangeNewKey] 是一個對象,我們可以通過 CGPointValue 去得到contentOffset
然后我們對 contentOffset 的 x 進行判斷,如果在最后一張圖片,即3后面的1時,將scrollView的contentOffset 設(shè)置為初始的1所在的位置,這里不能設(shè)置動畫
同理,如果在1前面的3時,將scrollView的contentOffset 設(shè)置為初始的3所在的位置,這里不能設(shè)置動畫
需要注意 pageControl 的設(shè)置也應(yīng)該實時設(shè)置
最后,我們將自己輪播的方法 scrollImage 填寫
-(void)scrollImage{ ? ? ? ? ? ?? ? ? NSInteger page=[self.pageControl currentPage]; ? ? page++; ? ? CGFloat offsetX= page * self.scrollView.frame.size.width+self.scrollView.frame.size.width; ? ?? ? ? [self.scrollView setContentOffset:CGPointMake(offsetX, 0) animated:YES]; }
從當(dāng)前的 page 滾動至下一個 page ,設(shè)置動畫
至此我們完成了支持滑動和自己定時播放的簡單頁面的輪播圖
相關(guān)文章
Objective-C中NSNumber與NSDictionary的用法簡介
這篇文章主要介紹了Objective-C中NSNumber與NSDictionary的用法簡介,雖然Objective-C即將不再是iOS的主流開發(fā)語言...well,需要的朋友可以參考下2015-09-09iOS 底部按鈕和應(yīng)用圖標顯示未讀消息(帶數(shù)字)
本文主要介紹了iOS 底部按鈕和應(yīng)用圖標顯示未讀消息的相關(guān)知識。具有很好的參考價值。下面跟著小編一起來看下吧2017-04-04一篇文章讓你看懂IOS中的block為何再也不需要WeakSelf弱引用
這篇文章主要給大家介紹了關(guān)于IOS中block為何再也不需要WeakSelf弱引用的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對各位iOS開發(fā)者們具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2018-01-01iOS 中根據(jù)屏幕寬度自適應(yīng)分布按鈕的實例代碼
這篇文章主要介紹了iOS 中根據(jù)屏幕寬度自適應(yīng)分布按鈕的實例代碼,本文給大家分享兩種方式,代碼簡單易懂,需要的朋友可以參考下2016-11-11