忙碌的工做终于开始有了闲暇,如今无事,整理一下我在项目中我我的觉的遇到的经典的并且很是容易受用的小例子。今天说的就是这广告位(banner图)顺时针自动轮播的问题,下面先来讲一下其实现原理(我以3张图为例):数组
1)首先咱们拿到数据后,肯定其中图片的个数安全
2)拿到图片的数组,不要急着直接使用,要从新将数组里面的数据放到一个MutableArray里面服务器
3)如何放置:(1)将获得数组的最后的一个对象array[count-1]放在MutableArray第一个位置(2)而后将获得的数组Array整个放到MutableArray里面(3)最后将获得的数组Array[0]的第1个元素添加到MutableArray的最后;这样咱们由原来数组的3个对象变成5个对象了学习
4)用从新获得的数组的元素个数建立scrollView的contentSize;注意:建立pagecontrol的时候仍是使用原来数组的count动画
原理说到这里:下面贴上我写的demo代码ui
#import "ViewController.h"atom
#define kScreenW [UIScreen mainScreen].bounds.size.widthurl
#define kImageHeight 150.0 //这个数根据美工那边的UI定spa
@interface ViewController ()<UIScrollViewDelegate> {orm
NSMutableArray *imageMutableArray;
}
@property (nonatomic, strong) NSArray *images;//放图片的数组
@property (nonatomic, strong) UIScrollView *bannerScrollView;
@property (nonatomic, strong) UIPageControl *pageControl;
@property (nonatomic, strong) NSTimer *timer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.images = @[@"1.png", @"2.png", @"3.png"];
[self setupBannerView];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self startTimer];
}
/**
* 若是图片(url)是从服务器上获得的,这个setupBannerView方法要写在数据请求完成以后调用
*/
- (void)setupBannerView {
UIView *bannerView = [[UIView alloc] initWithFrame:CGRectMake(0, 64, kScreenW, kImageHeight)];
bannerView.backgroundColor = [UIColor whiteColor];
[self.view addSubview:bannerView];
//1、先将图片交换放入新数组
imageMutableArray = [NSMutableArray array];
//作一个安全判断,而后呼唤第一张和最后一张图片的位置
if (self.images.count > 1) {
//将最后一张图片放在数组的第一个位置
[imageMutableArray addObject:self.images[self.images.count - 1]];
//再将数组整个放到数组中
[imageMutableArray addObjectsFromArray:self.images];
//将数组的第一张图片放在新数组的最后一个位置
[imageMutableArray addObject:self.images[0]];
} else {
//若是数组就只有一张图片,就没有必要在滚动了
[imageMutableArray addObjectsFromArray:self.images];
}
//2、建立scrollView
NSUInteger pageCount = imageMutableArray.count;//拿到新的数组中图片数量
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, kScreenW, kImageHeight)];
scrollView.contentSize = CGSizeMake(kScreenW * pageCount, kImageHeight);//设置可滑动的宽度
scrollView.pagingEnabled = YES;
scrollView.delegate = self;
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.showsVerticalScrollIndicator = NO;
//添加手势 能够进入到下一级
UITapGestureRecognizer *onceTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showBannerDetail)];
onceTapGesture.numberOfTapsRequired = 1;
[scrollView addGestureRecognizer:onceTapGesture];
self.bannerScrollView = scrollView;
[bannerView addSubview:self.bannerScrollView];
//设置开始启动的初始位置
[self.bannerScrollView setContentOffset:CGPointMake(kScreenW, 0) animated:NO];
//3、建立imageView并加载到scrollView上
for (int i = 0; i < pageCount; i ++) {
UIImageView *bannerImageView = [[UIImageView alloc] initWithFrame:CGRectMake(kScreenW * i, 0, kScreenW, kImageHeight)];
NSString *imageName = [NSString stringWithFormat:@"%d.png", (i)];
bannerImageView.image = [UIImage imageNamed:imageName];
[scrollView addSubview:bannerImageView];
}
//4、pageControl
NSUInteger count = self.images.count;//指示器的数量要跟图片的数量保持一致
UIPageControl *pageCrl = [[UIPageControl alloc] initWithFrame:CGRectMake((kScreenW - 100) / 2.0, 64 + (kImageHeight - 20) / 2.0, 100, 10)];
pageCrl.numberOfPages = count;//指示器的页数
pageCrl.currentPage = 0;//显示当前为第一页
pageCrl.pageIndicatorTintColor = [UIColor redColor];
pageCrl.currentPageIndicatorTintColor = [UIColor whiteColor];
[pageCrl addTarget:self action:@selector(updateImage) forControlEvents:UIControlEventValueChanged];
[bannerView addSubview:pageCrl];
self.pageControl = pageCrl;
//到这里基本上算是完成了,若是使得banner更严谨,下降Crash的频率作一下安全判断
self.bannerScrollView.scrollEnabled = count > 1;
//开启定时器
if (count > 1) {
[self startTimer];
//将scrollView从新定在第一页位置
[self.bannerScrollView setContentOffset:CGPointMake(kScreenW, 0) animated:NO];//将动画设置为no,用来营造假象
} else {
[self.bannerScrollView setContentOffset:CGPointZero animated:NO];
}
}
- (void)startTimer {
if (self.timer)
[self.timer invalidate];
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(updateImage) userInfo:nil repeats:YES];
self.timer = timer;
}
- (void)showBannerDetail {
NSUInteger currentPage = self.pageControl.currentPage;
NSLog(@"点击了%ld页", currentPage);
}
#pragma UIScrollViewDelegate
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
[self.timer invalidate];//当拖拽的时候,把定时器停掉。以免Crash
self.timer = nil;
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
[self startTimer];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
//修改Pages的当前页
if (scrollView == self.bannerScrollView) {
int index = scrollView.contentOffset.x / kScreenW;
if (index == 0) {
[self.bannerScrollView setContentOffset:CGPointMake(kScreenW * (imageMutableArray.count - 2), 0) animated:NO];
self.pageControl.currentPage = self.images.count - 1;
} else if (index == imageMutableArray.count - 1) {
[self.bannerScrollView setContentOffset:CGPointMake(kScreenW, 0) animated:NO];
self.pageControl.currentPage = 0;
} else {
self.pageControl.currentPage = index - 1;
}
}
}
- (void)updateImage {
NSInteger index = self.bannerScrollView.contentOffset.x / kScreenW;
//前面为了使轮播图向同一个方向滚动,在第一个位置放置的是最后的一个图片,因此正式的开始是从第二个位置开始的,这是为了给肉眼形成假象
index = (index + 1) % (self.images.count + 2);
if (index == self.images.count + 1) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self.bannerScrollView setContentOffset:CGPointMake(kScreenW, 0) animated:NO];
});
}
[self.bannerScrollView setContentOffset:CGPointMake(index * kScreenW, 0) animated:YES];
//当显示的是第一张图的时候,指示器显示第一个
if (index == 0) {
self.pageControl.currentPage = self.images.count - 1;
} else if (index == self.images.count + 1) {
self.pageControl.currentPage = 0;
} else {
self.pageControl.currentPage = index - 1;
}
}
效果图:
代码是我看别人的博客后根据本身的理解想着写的,学习没有什么捷径,只能靠本身亲手写,才能理解其中的原理,上面的例子没有通过什么繁琐的封装,只是简单的广告轮播,另外,若是我写的代码有不足的地方欢迎指正。相互学习吧。