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 (weak, nonatomic, readonly) UIPageControl *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