首頁 > 軟體

iOS簡單實現輪播圖效果

2022-08-05 18:01:16

本文範例為大家分享了iOS簡單實現輪播圖效果的具體程式碼,供大家參考,具體內容如下

平常在開發過程中,首頁的輪播圖總是少不了,輪播圖我們都知道肯定是要使用 UIScrollView ,難點就在最後一張圖片被滑動時,如何回到第一張圖片以及第一張滑動到最後一張。
我們可以使用如下方式實現輪播圖,在劃到3後面的1後,設定 contentOffset 回到最先的1,並設定 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

在建立View的時候使用 initWithFrame:(CGRect)frame imgArray:(NSArray *)array,傳入需要展示的 imgArray ,在 view 內進行處理。

在該方法的實現中,首先就是對圖片陣列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];

很簡單,就是一些屬性、代理的設定 根據 imgArray 的大小設定 contentSize ,另外對 contentOffset 新增一個觀察者,方便後續對pageControl和contentOffset進行設定。

然後,我們根據 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];

這裡設定的是5秒鐘後自動捲動輪播圖,可以根據需要自己設定,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 對應的 pageControl 的 page ,需要注意的是在第一張圖片之前還有最後一張圖片,所以計算的時候需要-1

2.scrollViewWillBgeinDragging:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
    [self.timer invalidate];
    self.timer=nil;
}

在scrollView即將被划動時,取消自動輪播,將timer設定為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];
    
    //優先順序 設定到當前的runloop中
    NSRunLoop *runloop=[NSRunLoop currentRunLoop];
    [runloop addTimer:self.timer forMode:NSRunLoopCommonModes];
}

在將要結束划動的時候,重新設定timer 並新增到當前的runloop中

實現輪播圖的核心程式碼

對 contentOffset 的監聽

- (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];
        //當劃到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;
        }
        //當劃到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 設定為初始的1所在的位置,這裡不能設定動畫

同理,如果在1前面的3時,將scrollView的contentOffset 設定為初始的3所在的位置,這裡不能設定動畫

需要注意 pageControl 的設定也應該實時設定

最後,我們將自己輪播的方法 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];
}

從當前的 page 捲動至下一個 page ,設定動畫

至此我們完成了支援滑動和自己定時播放的簡單頁面的輪播圖


IT145.com E-mail:sddin#qq.com