1. 程式人生 > >UIScrollView圖片迴圈輪播

UIScrollView圖片迴圈輪播

實現無限滾動檢視的方法大體上分為倆種,一種是利用collectionView實現無限滾動,因為collectionView本身存在著複用的問題,所以不用擔心記憶體的消耗問題,就是使用的時候程式碼相對比較多一點,這裡著重介紹第二種,也就是UIScrollView的實現方法。

假如我們現在要顯示5張圖片,最簡單的就是我們直接建立5+2個,也就是7個imageView,而我們的存放順序為,圖片5,圖片1,圖片2,圖片3,圖片4,圖片5,圖片1。預設顯示第2張(圖片1),一直向右滑動到第6張(圖片5),再向右滑動顯示第7張(圖片1)顯示完成後,將UIScrollView的contentOffset設定到第2個imageView上(圖片1),這時候便可繼續向右滑動實現迴圈的效果;同理,向左滑動時,滑動到第1張(圖片5)後,將UIScrollView的contentOffset設定到第6個imageView上(圖片5),這樣便可以繼續向左滑動實現迴圈效果。

效能優化:
上面的那種方法,需要我們建立n+2個imageView,而這些imageView都需要載入到記憶體中去,所以還有一種簡單的方法來實現,只需要建立三個imageView便可以實現無限迴圈。

實現原理:
比如有5張圖片,建立三個imageView,分別展示圖片5,圖片1,圖片2,預設展示第二張(圖片1),向左滑動顯示第3張(圖片2),顯示完成後,將scrollView的contentOffset重新設定到中間圖片,並根據引用計數+1,重新重新整理圖片,三個imageView分別展示為,圖片1,圖片2,圖片3,這時候就相當於圖片2在中間,圖片3在右邊。同理再次向右滑動,顯示圖片第3張(圖片3),顯示完成後,再將scrollView的contentOffset重新設定到中間圖片上面,並根據引用計數+1,重新重新整理圖片,三個imageView分別展示為圖片2,圖片3,圖片4,這時候就相當於圖片3在中間,圖片4在右邊,依次下去,便可實現無限迴圈。

注意點:使用迴圈播放,要處理好下標越界的問題。處理方法就直接寫在程式碼裡。


#import <UIKit/UIKit.h>

@interface SZInfiniteLoopScrollView :UIView

/**需要新增的圖片陣列*/

@property (strong,nonatomic) NSArray *images;

/**控制水平豎直方向的滾動預設為水平方向設定為YES時為豎直方向*/

@property (assign,nonatomic, getter=isInfiniteScrollVertical)BOOL infiniteScrollVertical;

/** 圖片切換時間 */

@property(nonatomic,assign) CGFloat time;

@end

#import "SZInfiniteLoopScrollView.h"

/** ImageView的個數 */

staticintconst ImageViewCount = 3;

@interface SZInfiniteLoopScrollView ()<UIScrollViewDelegate>

/* 頁碼控制器 */

@property (weaknonatomicreadonlyUIPageControl *pageControl;

@property (weak,nonatomic) UIScrollView *scrollView;

/* 定時器 */

@property (weak,nonatomic) NSTimer *timer;

@end

@implementation SZInfiniteLoopScrollView

//構造方法

- (instancetype)initWithFrame:(CGRect)frame

{

if (self = [superinitWithFrame:frame]) {  

//滾動檢視

UIScrollView *scrollView = [[UIScrollViewalloc] init];

        scrollView.showsHorizontalScrollIndicator =NO;

        scrollView.showsVerticalScrollIndicator =NO;

        scrollView.pagingEnabled =YES;

        scrollView.bounces =NO;

        scrollView.delegate =self;

        [selfaddSubview:scrollView];

_scrollView = scrollView;

//圖片控制元件

for (int i =0; i<ImageViewCount; i++) {

UIImageView *imageView = [[UIImageViewalloc] init];

            [scrollView addSubview:imageView];

        }

//頁碼檢視

UIPageControl *pageControl = [[UIPageControlalloc] init];

        [selfaddSubview:pageControl];

_pageControl = pageControl;

    }

returnself;

}

#pragma mark - 佈局子控制元件

- (void)layoutSubviews

{

    [superlayoutSubviews];

//設定frame

_scrollView.frame =self.bounds;

//設定contentSize

if (self.isInfiniteScrollVertical) {//垂直滾動

self.scrollView.contentSize = CGSizeMake(0,ImageViewCount *self.bounds.size.height);

    } else {

self.scrollView.contentSize = CGSizeMake(ImageViewCount *self.bounds.size.width,0);

    }

//擺放imageView

for (int i =0; i<ImageViewCount; i++) {

UIImageView *imageView =self.scrollView.subviews[i];

if (self.isInfiniteScrollVertical) {

            imageView.frame =CGRectMake(0, i *self.scrollView.frame.size.height,

            self.scrollView.frame.size.width,self.scrollView.frame.size.height);

        } else {

            imageView.frame =CGRectMake(i * self.scrollView.frame.size.width,0,

            self.scrollView.frame.size.width,self.scrollView.frame.size.height);

        }

    }

// 設定pageControl

CGFloat pageW =80;

CGFloat pageH =20;

CGFloat pageX =self.scrollView.frame.size.width - pageW;

CGFloat pageY =self.scrollView.frame.size.height - pageH;

self.pageControl.frame =CGRectMake(pageX, pageY, pageW, pageH);

    [selfupdateContent];

}

#pragma mark - setter

- (void)setImages:(NSArray *)images

{

_images = images;

//設定頁碼

self.pageControl.numberOfPages = images.count;

self.pageControl.currentPage = 0;

//設定內容

    [selfupdateContent];

//開始定時器

    [selfstartTimer];

}

- (void)setTime:(CGFloat)time{

_time = time;

}

#pragma mark - <UIScrollViewDelegate>

- (void)scrollViewDidScroll:(UIScrollView *)scrollView

{

//計算當前頁碼(找出當前顯示在最中間的imageView

NSInteger page =0;

CGFloat minDistance =MAXFLOAT;

for (int i =0; i<ImageViewCount; i++) {

UIImageView *imageView =self.scrollView.subviews[i];

CGFloat distance =0;

if (self.isInfiniteScrollVertical) {

            distance = ABS(imageView.frame.origin.y - scrollView.contentOffset.y);

        } else {

            distance = ABS(imageView.frame.origin.x - scrollView.contentOffset.x);

        }

if (distance < minDistance) {

            minDistance = distance;

            page = imageView.tag;

        }

    }

self.pageControl.currentPage = page;

}

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView

{

    [selfstopTimer];

}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate

{

    [selfstartTimer];

}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView

{

    [selfupdateContent];

}

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView

{

    [selfupdateContent];

}

#pragma mark - 內容更新

- (void)updateContent

{

//設定圖片

for (int i =0; i<ImageViewCount; i++) {

UIImageView *imageView =self.scrollView.subviews[i];

//當前頁碼

NSInteger index =self.pageControl.currentPage;

if (i ==0) {//左邊顯示上一頁

            index--;

        } elseif (i == 2) {//右邊顯示下一頁

            index++;

        }

//越界處理

if (index <0) {

            index = self.pageControl.numberOfPages -1;

        } elseif (index >= self.pageControl.numberOfPages) {

            index = 0;

        }

        imageView.tag = index;

        imageView.image =self.images[index];

    }

//設定偏移量在中間

if (self.isInfiniteScrollVertical) {

self.scrollView.contentOffset = CGPointMake(0,self.scrollView.frame.size.height);

    } else {

self.scrollView.contentOffset = CGPointMake(self.scrollView.frame.size.width,0);

    }   

}

#pragma mark - 定時器處理

- (void)startTimer

{

NSTimer *timer = [NSTimertimerWithTimeInterval:self.timetarget:selfselector:@selector(next)userInfo:nilrepeats:YES];

    [[NSRunLoopmainRunLoop] addTimer:timerforMode:NSRunLoopCommonModes];

self.timer = timer;

}

- (void)stopTimer

{

    [self.timerinvalidate];

self.timer =nil;

}

//下一張圖片

- (void)next

{

if (self.isInfiniteScrollVertical) {

        [self.scrollViewsetContentOffset:CGPointMake(0,2 * self.scrollView.frame.size.height)

         animated:YES];

    } else {

        [self.scrollViewsetContentOffset:CGPointMake(2 *self.scrollView.frame.size.width,0)

         animated:YES];

    }

}

//整合圖片輪播

#import "ViewController.h"

#import "SZInfiniteLoopScrollView.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {

    [superviewDidLoad];

    [selfsetupInfiniteScrollView];

}

//圖片輪播

- (void)setupInfiniteScrollView{

SZInfiniteLoopScrollView *scrollView = [[SZInfiniteLoopScrollViewalloc] init];

//尺寸

    scrollView.frame =CGRectMake(0,0, self.view.frame.size.width,300);

//圖片切換時間

    scrollView.time =2;

//圖片陣列

    scrollView.images =@[

                          [UIImageimageNamed:@"img_00"],

                          [UIImageimageNamed:@"img_01"],

                          [UIImageimageNamed:@"img_02"],

                          [UIImageimageNamed:@"img_03"],

                          [UIImageimageNamed:@"img_04"]

];

    [self.viewaddSubview:scrollView];

//    //豎直方向的滾動

//    SZInfiniteLoopScrollView *scrollView1 = [[SZInfiniteLoopScrollView alloc] init];

//    

//    scrollView1.frame = CGRectMake(0, 250, self.view.frame.size.width, 100);

//    scrollView1.images = @[

//                           [UIImage imageNamed:@"img_00"],

//                           [UIImage imageNamed:@"img_01"],

//                           [UIImage imageNamed:@"img_02"],

//                           [UIImage imageNamed:@"img_03"],

//                           [UIImage imageNamed:@"img_04"]

//                           ];

//    

//    [self.view addSubview:scrollView1];

//設定豎直方向滾動

//    scrollView1.infiniteScrollVertical = YES;

}

@end