IOS实现自动循环滚动广告--ScrollView的优化和封装

一、问题分析

  在许多App中,我们都会见到循环滚动的视图,比如广告,其实想实现这个功能并不难,用ScrollView就可以轻松完成,但是在制作的过程中还存在几个小问题,如果能够正确的处理好这些小问题,无论从效果还是性能上都会得到优化。

问题一

  第一个问题是如何用ScrollView来展示N个视图。想要实现这个效果,可以把N个视图依次按顺序添加到ScrollView上,然后把 ScrollView的contentSize设置为N个视图的尺寸,通过滑动ScrollView来查看加在上面的视图。

问题二

  第二个问题是如何完成图片的循环滚动,也就是展示完最后一张之后会接着展示第一张,形成图片的循环展示。想要实现这个效果,首先需要让ScrollView实现自动分页,这样可以保证滑动结束展示的是完整的视图;其次,需要根据当前展示的页数来设置ScrollView的contentOffset。

  对于第一个问题的解决是用的最简单的方式,但实际上忽略了一个很重要的问题,那就是如果要展示的视图数量N非常大的时候,我们该如何做呢?假设通过ScrollView来展示的每个视图的宽度恰好是屏幕的宽度,那么在展示的时候,其实能够呈现在我们眼前的最多只有两个视图,也就是要么是完整的一个视图,要么是两个不完整的视图。因此,我们只需要有三个视图,就能够完成循环的展示。

问题三

  第三个问题是在循环滚动的过程中,希望知道当前的页数,这个页数可以通过contentOffset.x来计算,通常会用UIPageControl来表示。此外,当点击某一个视图的时候,要能够知道当前点击的视图是哪一个。

问题四

  第四个问题是自动展示下一页的功能,这个需要写好跳到下一页的方法,然后通过NSTimer定时器来完成。

  除了上面的几个问题,大家也可以为其添加更多的功能。那么对于ScrollView自动翻页这样通用的功能,最好的方式是将其封装起来,这样可以大大的提高效率。下面的代码是把UIScrollView、UIPageControl封装到了一个UIView中,而其中的ScrollView用来循环展示多张图片。

二、功能实现

1、封装Scrollview代码.h:

 1 //  WHScrollAndPageView.h
 2 //  循环滚动视图
 3 //
 4 //  Created by jereh on 15-3-15.
 5 //  Copyright (c) 2015年 jereh. All rights reserved.
 6 //
 7  
 8 #import <uikit uikit.h="">
 9  
10 @protocol WHcrollViewViewDelegate;
11  
12 @interface WHScrollAndPageView : UIView <uiscrollviewdelegate>
13 {
14     __unsafe_unretained id <whcrollviewviewdelegate> _delegate;
15 }
16  
17 @property (nonatomic, assign) id <whcrollviewviewdelegate> delegate;
18  
19 @property (nonatomic, assign) NSInteger currentPage;
20  
21 @property (nonatomic, strong) NSMutableArray *imageViewAry;
22  
23 @property (nonatomic, readonly) UIScrollView *scrollView;
24  
25 @property (nonatomic, readonly) UIPageControl *pageControl;
26  
27 -(void)shouldAutoShow:(BOOL)shouldStart;
28  
29 @end
30  
31 @protocol WHcrollViewViewDelegate <nsobject>
32  
33 @optional
34 - (void)didClickPage:(WHScrollAndPageView *)view atIndex:(NSInteger)index;
35  
36 @end</nsobject></whcrollviewviewdelegate></whcrollviewviewdelegate></uiscrollviewdelegate></uikit>

2、封装Scrollview代码.m:

  1 //  WHScrollAndPageView.m
  2 //  循环滚动视图
  3 //
  4 //  Created by jereh on 15-3-15.
  5 //  Copyright (c) 2015年 jereh. All rights reserved.
  6 //
  7  
  8 #import "WHScrollAndPageView.h"
  9  
 10 @interface WHScrollAndPageView ()
 11 {
 12     UIView *_firstView;
 13     UIView *_middleView;
 14     UIView *_lastView;
 15      
 16     float _viewWidth;
 17     float _viewHeight;
 18      
 19     NSTimer *_autoScrollTimer;
 20      
 21     UITapGestureRecognizer *_tap;
 22 }
 23  
 24 @end
 25  
 26 @implementation WHScrollAndPageView
 27  
 28 - (id)initWithFrame:(CGRect)frame
 29 {
 30     self = [super initWithFrame:frame];
 31     if (self) {
 32      
 33         _viewWidth = self.bounds.size.width;
 34         _viewHeight = self.bounds.size.height;
 35          
 36         //设置scrollview
 37         _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, _viewWidth, _viewHeight)];
 38         _scrollView.delegate = self;
 39         _scrollView.contentSize = CGSizeMake(_viewWidth * 3, _viewHeight);
 40         _scrollView.showsHorizontalScrollIndicator = NO;
 41         _scrollView.pagingEnabled = YES;
 42         _scrollView.backgroundColor = [UIColor blackColor];
 43         _scrollView.delegate = self;
 44         [self addSubview:_scrollView];
 45          
 46         //设置分页
 47         _pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(0, _viewHeight-30, _viewWidth, 30)];
 48         _pageControl.userInteractionEnabled = NO;
 49         _pageControl.currentPageIndicatorTintColor = [UIColor redColor];
 50         _pageControl.pageIndicatorTintColor = [UIColor whiteColor];
 51         [self addSubview:_pageControl];
 52          
 53         //设置单击手势
 54         _tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleTap:)];
 55         _tap.numberOfTapsRequired = 1;
 56         _tap.numberOfTouchesRequired = 1;
 57         [_scrollView addGestureRecognizer:_tap];
 58     }
 59     return self;
 60 }
 61  
 62 #pragma mark 单击手势
 63 -(void)handleTap:(UITapGestureRecognizer*)sender
 64 {
 65     if ([_delegate respondsToSelector:@selector(didClickPage:atIndex:)]) {
 66         [_delegate didClickPage:self atIndex:_currentPage+1];
 67     }
 68 }
 69  
 70 #pragma mark 设置imageViewAry
 71 -(void)setImageViewAry:(NSMutableArray *)imageViewAry
 72 {
 73     if (imageViewAry) {
 74         _imageViewAry = imageViewAry;
 75         _currentPage = 0; //默认为第0页
 76          
 77         _pageControl.numberOfPages = _imageViewAry.count;
 78     }
 79      
 80     [self reloadData];
 81 }
 82  
 83 #pragma mark 刷新view页面
 84 -(void)reloadData
 85 {
 86     [_firstView removeFromSuperview];
 87     [_middleView removeFromSuperview];
 88     [_lastView removeFromSuperview];
 89      
 90     //从数组中取到对应的图片view加到已定义的三个view中
 91     if (_currentPage==0) {
 92         _firstView = [_imageViewAry lastObject];
 93         _middleView = [_imageViewAry objectAtIndex:_currentPage];
 94         _lastView = [_imageViewAry objectAtIndex:_currentPage+1];
 95     }
 96     else if (_currentPage == _imageViewAry.count-1)
 97     {
 98         _firstView = [_imageViewAry objectAtIndex:_currentPage-1];
 99         _middleView = [_imageViewAry objectAtIndex:_currentPage];
100         _lastView = [_imageViewAry firstObject];
101     }
102     else
103     {
104         _firstView = [_imageViewAry objectAtIndex:_currentPage-1];
105         _middleView = [_imageViewAry objectAtIndex:_currentPage];
106         _lastView = [_imageViewAry objectAtIndex:_currentPage+1];
107     }
108      
109     //设置三个view的frame,加到scrollview上
110     _firstView.frame = CGRectMake(0, 0, _viewWidth, _viewHeight);
111     _middleView.frame = CGRectMake(_viewWidth, 0, _viewWidth, _viewHeight);
112     _lastView.frame = CGRectMake(_viewWidth*2, 0, _viewWidth, _viewHeight);
113     [_scrollView addSubview:_firstView];
114     [_scrollView addSubview:_middleView];
115     [_scrollView addSubview:_lastView];
116      
117     //设置当前的分页
118     _pageControl.currentPage = _currentPage;
119      
120     //显示中间页
121     _scrollView.contentOffset = CGPointMake(_viewWidth, 0);
122 }
123  
124 #pragma mark scrollvie停止滑动
125 -(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
126 {
127     //手动滑动时候暂停自动替换
128     [_autoScrollTimer invalidate];
129     _autoScrollTimer = nil;
130     _autoScrollTimer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(autoShowNextImage) userInfo:nil repeats:YES];
131      
132     //得到当前页数
133     float x = _scrollView.contentOffset.x;
134      
135     //往前翻
136     if (x<=0) {
137         if (_currentPage-1<0) {
138             _currentPage = _imageViewAry.count-1;
139         }else{
140             _currentPage --;
141         }
142     }
143      
144     //往后翻
145     if (x>=_viewWidth*2) {
146         if (_currentPage==_imageViewAry.count-1) {
147             _currentPage = 0;
148         }else{
149             _currentPage ++;
150         }
151     }
152      
153     [self reloadData];
154 }
155  
156 #pragma mark 自动滚动
157 -(void)shouldAutoShow:(BOOL)shouldStart
158 {
159     if (shouldStart)  //开启自动翻页
160     {
161         if (!_autoScrollTimer) {
162             _autoScrollTimer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(autoShowNextImage) userInfo:nil repeats:YES];
163         }
164     }
165     else   //关闭自动翻页
166     {
167         if (_autoScrollTimer.isValid) {
168             [_autoScrollTimer invalidate];
169             _autoScrollTimer = nil;
170         }
171     }
172 }
173  
174 #pragma mark 展示下一页
175 -(void)autoShowNextImage
176 {
177     if (_currentPage == _imageViewAry.count-1) {
178         _currentPage = 0;
179     }else{
180         _currentPage ++;
181     }
182      
183     [self reloadData];
184 }
185  
186 @end

3、使用封装好的Scrollview代码.m:

 1 //  ViewController.m
 2 //  循环滚动视图
 3 //
 4 //  Created by jereh on 15-3-15.
 5 //  Copyright (c) 2015年 jereh. All rights reserved.
 6 //
 7  
 8 #import "ViewController.h"
 9 #import "WHScrollAndPageView.h"
10 #define NUM 10
11  
12 @interface ViewController ()<whcrollviewviewdelegate>
13 {
14     WHScrollAndPageView *_whView;
15 }
16  
17 @end
18  
19 @implementation ViewController
20  
21 - (void)viewDidLoad
22 {
23     [super viewDidLoad];
24      
25     //创建view (view中包含UIScrollView、UIPageControl,设置frame)
26     _whView = [[WHScrollAndPageView alloc] initWithFrame:CGRectMake(0, 44, 320, 400)];
27      
28     //把N张图片放到imageview上
29     NSMutableArray *tempAry = [NSMutableArray array];
30     for (int i=1; i<num; _whview="" _whview.delegate="self;" animated="" imageview="[[UIImageView" imageview.image="[UIImage" index="" mark="" nsstring="" pragma="" pre="" self.view="" tempary="" uiimageview="" view="" whscrollandpageview=""><p> </p></num;></whcrollviewviewdelegate>

 

原文地址:https://www.cnblogs.com/xjy-123/p/5190993.html