iOS簡(jiǎn)單實(shí)現(xiàn)輪播圖效果
本文實(shí)例為大家分享了iOS簡(jiǎn)單實(shí)現(xiàn)輪播圖效果的具體代碼,供大家參考,具體內(nèi)容如下
平常在開(kāi)發(fā)過(guò)程中,首頁(yè)的輪播圖總是少不了,輪播圖我們都知道肯定是要使用 UIScrollView ,難點(diǎn)就在最后一張圖片被滑動(dòng)時(shí),如何回到第一張圖片以及第一張滑動(dòng)到最后一張。
我們可以使用如下方式實(shí)現(xiàn)輪播圖,在劃到3后面的1后,設(shè)置 contentOffset 回到最先的1,并設(shè)置 pageControl ,即可達(dá)到效果 (從1劃到3也同理)
看一下效果:
完成這種輪播圖,我們的 View 需要如下的屬性和方法
@interface RoundView : UIView ? @property (nonatomic,strong) UIScrollView ? *scrollView; //存放ScrollView每一個(gè)page的圖片的array @property (nonatomic) NSMutableArray ? ? ? ?*imgArray; @property (nonatomic) UIPageControl ? ? ? ? *pageControl; //定時(shí)器 @property (nonatomic,strong) NSTimer ? ? ? ?*__nullable timer; ? - (instancetype)initWithFrame:(CGRect)frame imgArray:(NSArray *)array; ? @end
在創(chuàng)建View的時(shí)候使用 initWithFrame:(CGRect)frame imgArray:(NSArray *)array,傳入需要展示的 imgArray ,在 view 內(nèi)進(jìn)行處理。
在該方法的實(shí)現(xiàn)中,首先就是對(duì)圖片數(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 就變成了最開(kāi)始演示原理的樣式,為 @[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];
很簡(jiǎn)單,就是一些屬性、代理的設(shè)置 根據(jù) imgArray 的大小設(shè)置 contentSize ,另外對(duì) contentOffset 添加一個(gè)觀察者,方便后續(xù)對(duì)pageControl和contentOffset進(jìn)行設(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]; ? ? ? ? //這里我就不傳入圖片了,測(cè)試的imgArray中為顏色,使用顏色替代 ? ? ? ? imgView.backgroundColor=self.imgArray[i]; ? ? ? ? [self.scrollView addSubview:imgView]; ? ? }
然后對(duì)pageControl和timer進(jìn)行初始化
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秒鐘后自動(dòng)滾動(dòng)輪播圖,可以根據(jù)需要自己設(shè)置,scrollmage 方法后面會(huì)講
我們看一下我們需要的 scrollView 的代理方法
1.scrollViewDidScroll:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{ ? ? CGFloat offsetX=scrollView.contentOffset.x; ? ? offsetX+=scrollView.frame.size.width*0.5; ? ?? ? ? //因?yàn)樽钋懊孢€有一個(gè)imgView ? ? int page=offsetX/scrollView.frame.size.width-1; ? ? self.pageControl.currentPage=page; ? ?? }
此方法用來(lái)計(jì)算 contentOffset 對(duì)應(yīng)的 pageControl 的 page ,需要注意的是在第一張圖片之前還有最后一張圖片,所以計(jì)算的時(shí)候需要-1
2.scrollViewWillBgeinDragging:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{ ? ? [self.timer invalidate]; ? ? self.timer=nil; }
在scrollView即將被劃動(dòng)時(shí),取消自動(dòng)輪播,將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)先級(jí) 設(shè)置到當(dāng)前的runloop中 ? ? NSRunLoop *runloop=[NSRunLoop currentRunLoop]; ? ? [runloop addTimer:self.timer forMode:NSRunLoopCommonModes]; }
在將要結(jié)束劃動(dòng)的時(shí)候,重新設(shè)置timer 并添加到當(dāng)前的runloop中
實(shí)現(xiàn)輪播圖的核心代碼
對(duì) contentOffset 的監(jiān)聽(tīng)
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{ ? ?? ? ? if([keyPath isEqualToString:@"contentOffset"]){ ? ? ? ? //[change objectForKey:NSKeyValueChangeNewKey] 是一個(gè)對(duì)象 ? ? ? ? CGPoint offset= [[change objectForKey:NSKeyValueChangeNewKey] CGPointValue]; ? ? ? ? //當(dāng)劃到3后面的1時(shí) ? ? ? ? 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時(shí) ? ? ? ? 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] 是一個(gè)對(duì)象,我們可以通過(guò) CGPointValue 去得到contentOffset
然后我們對(duì) contentOffset 的 x 進(jìn)行判斷,如果在最后一張圖片,即3后面的1時(shí),將scrollView的contentOffset 設(shè)置為初始的1所在的位置,這里不能設(shè)置動(dòng)畫
同理,如果在1前面的3時(shí),將scrollView的contentOffset 設(shè)置為初始的3所在的位置,這里不能設(shè)置動(dòng)畫
需要注意 pageControl 的設(shè)置也應(yīng)該實(shí)時(shí)設(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 滾動(dòng)至下一個(gè) page ,設(shè)置動(dòng)畫
至此我們完成了支持滑動(dòng)和自己定時(shí)播放的簡(jiǎn)單頁(yè)面的輪播圖
相關(guān)文章
iOS開(kāi)發(fā)實(shí)現(xiàn)下載器的基本功能(1)
這篇文章主要為大家詳細(xì)介紹了iOS開(kāi)發(fā)實(shí)現(xiàn)下載器基本功能的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-07-07iOS中sqlite數(shù)據(jù)庫(kù)的原生用法
這篇文章主要為大家詳細(xì)介紹了iOS中sqlite數(shù)據(jù)庫(kù)的原生用法,sqlite數(shù)據(jù)庫(kù)相信各位早已耳聞,非常輕巧的一個(gè)數(shù)據(jù)庫(kù),數(shù)據(jù)庫(kù)僅一個(gè)文件,即建即用,感興趣的小伙伴們可以參考一下32016-05-05IOS設(shè)置QQ小紅點(diǎn)消除的方法(一鍵退朝)
這篇文章主要介紹了IOS設(shè)置QQ小紅點(diǎn)消除的方法(一鍵退朝),對(duì)ios設(shè)置小紅點(diǎn)消除相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧2016-01-01Objective-C中NSNumber與NSDictionary的用法簡(jiǎn)介
這篇文章主要介紹了Objective-C中NSNumber與NSDictionary的用法簡(jiǎn)介,雖然Objective-C即將不再是iOS的主流開(kāi)發(fā)語(yǔ)言...well,需要的朋友可以參考下2015-09-09iOS 底部按鈕和應(yīng)用圖標(biāo)顯示未讀消息(帶數(shù)字)
本文主要介紹了iOS 底部按鈕和應(yīng)用圖標(biāo)顯示未讀消息的相關(guān)知識(shí)。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧2017-04-04一篇文章讓你看懂IOS中的block為何再也不需要WeakSelf弱引用
這篇文章主要給大家介紹了關(guān)于IOS中block為何再也不需要WeakSelf弱引用的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)各位iOS開(kāi)發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2018-01-01iOS 中根據(jù)屏幕寬度自適應(yīng)分布按鈕的實(shí)例代碼
這篇文章主要介紹了iOS 中根據(jù)屏幕寬度自適應(yīng)分布按鈕的實(shí)例代碼,本文給大家分享兩種方式,代碼簡(jiǎn)單易懂,需要的朋友可以參考下2016-11-11