接触到新的需求,要求在app首页加上轮播的广告栏
在这里记录一下实现思路
首先,明确这里需要哪些基础的控件
/**
* 最基础的滑动视图
*/
@property (nonatomic ,strong) UIScrollView *scrollView;
/**
* 用于标示当且页面位置的小点
*/
@property (nonatomic ,strong) UIPageControl *pageControl;
控件有了,想一想把图片展示出来尚且需要数据源,所以需要一个数组来储存图片信息(本地图片的话可以直接储存图片名,网络图片储存图片的URL即可)
/**
* 图片源
*/
@property (nonatomic, strong) NSArray * imageArray;
现在看起来似乎已经实现了,但是要是让它实现自动轮播的话不免要增加一个定时器来控制滚动时间。图片也不能单纯用来展示,也要有点击事件。
/**
* 用于计时实现自动滚动
*/
@property (nonatomic ,strong) NSTimer *timer;
/**
* 这里用于增加图片点击事件,实现跳转
*/
@property (nonatomic ,copy) void(^actionBlock)(NSInteger index );
另外,为了判断是使用本地图片或者是网络图片需要一个布尔型标示
BOOL _isUrl;
前期需要的部件都已经声明完毕了,接下来就谈谈怎么实现
初始化滚动视图scrollview
_scrollView = [[UIScrollView alloc] initWithFrame:self.frame];
_scrollView.delegate = self;
//设置横竖向滚动条隐藏
_scrollView.showsHorizontalScrollIndicator = NO;
_scrollView.showsVerticalScrollIndicator = NO;
_scrollView.pagingEnabled = YES;
//增加手势,图片的点击事件
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(pageViewClick:)];
[_scrollView addGestureRecognizer:tapGesture];
[_self addSubview:scrollView];
滚动视图添加完毕之后该思考如何将图片加载到滚动视图里
这里拿只需要三个滚动页面做例子解释一下:
想要实现循环滚动,最简单的方法就是实际上加载五张图在滚动视图里面,就是把最后一张图拷贝一份放到最前面,第一张图拷贝一份加在最后面。(如下图,5和2一样,1和4一样)这样一来从第一张(图2)直接右滑就可以过渡到最后一张(其实是滑到了图1,并不是真正的循环到图4)。同理,最后一张左划也可以过渡到第一张。这样一来就可以实现完美的左右循环滑动了。(其实只是在视觉上欺骗了用户,以为真正的循环滑到了第一张或者最后一张,其实只不过是拷贝)
代码就是
- (void)setADPageImage {
//判断数据源中是否只有一张图
if (_imageArray.count > 1) {
//大于一张图,循环创建imageView用来显示图片(实际创建了imageArray.count + 2张图片)
for (int i = 0; i < _imageArray.count + 2; i ++) {
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(self.frame.size.width * i, 0, self.frame.size.width, self.frame.size.height)];
//设置图片填充模式
imageView.contentMode = UIViewContentModeScaleToFill;
imageView.backgroundColor = [UIColor whiteColor];
[_ADScrollView addSubview:imageView];
if (i == 0) {
//把最后一张图拷贝一份放在最前面
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (_isUrl) {
//如果是网络图片,根据url获取图片
NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:_imageArray[_imageArray.count - 1]]];
UIImage *image = [UIImage imageWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
if (data) {
imageView.image = image;
}
});
} else {
//如果是本地图片,根据图片名称获取图片
NSString *imageName = _imageArray[_imageArray.count - 1];
dispatch_async(dispatch_get_main_queue(), ^{
imageView.image = [UIImage imageNamed:imageName];
});
}
});
} else if (i == _imageArray.count + 1) {
//将第一张图拷贝一份放到最后面
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (_isUrl) {
NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:_imageArray[0]]];
UIImage *image = [UIImage imageWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
imageView.image = image;
});
} else {
NSString *imageName = _imageArray[0];
dispatch_async(dispatch_get_main_queue(), ^{
imageView.image = [UIImage imageNamed:imageName];
});
}
});
} else {
//其余正常添加
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (_isUrl) {
NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:_imageArray[i - 1]]];
UIImage *image = [UIImage imageWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
imageView.image = image;
});
} else {
NSString *imageName = _imageArray[i - 1];
dispatch_async(dispatch_get_main_queue(), ^{
imageView.image = [UIImage imageNamed:imageName];
});
}
});
}
//设置滚动视图的contentSize
_ADScrollView.contentSize = CGSizeMake((_imageArray.count + 2) * self.frame.size.width,0);
//设置起始位置
_ADScrollView.contentOffset = CGPointMake(self.frame.size.width, 0);
}
} else {
//只有一张图片的情况
UIImageView *imageView = [[UIImageView alloc] initWithFrame:_ADScrollView.frame];
imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.clipsToBounds = YES;
imageView.image = [UIImage imageNamed:_imageArray[0]];
[self addSubview:imageView];
[_ADScrollView removeFromSuperview];
}
}
广告滚动视图添加完毕之后,要设置表示当前页面的小圆圈(pageControl)
- (void)setADPageControl {
_pageControl = [[UIPageControl alloc] init];
//设置pageControl的默认背景颜色是透明
_pageControl.backgroundColor = [UIColor clearColor];
//设置pageControl的小圆圈默认景颜色为白色
_pageControl.pageIndicatorTintColor = [UIColor whiteColor];
//设置pageControl的小圆圈当前背景颜色为红色
_pageControl.currentPageIndicatorTintColor = [Color colorWithHexColorString:@"EC455A" andAlpha:1.0f];
//设置页面数量
_pageControl.numberOfPages = _imageArray.count;
//默认是0
_pageControl.currentPage = 0;
//自动计算大小尺寸
CGSize pageSize = [_pageControl sizeForNumberOfPages:_imageArray.count];
//设置pageControl位置
_pageControl.bounds = CGRectMake(0, 0, self.frame.size.width, pageSize.height);
_pageControl.center = CGPointMake(self.frame.size.width/2.0, self.frame.size.height-_pageControl.frame.size.height/2.0);
//设置响应事件
[_pageControl addTarget:self action:@selector(pageChange:) forControlEvents:UIControlEventValueChanged];
[self addSubview:_pageControl];
self.pageControl = _pageControl;
}
-(void)pageChange:(UIPageControl *)page {
//获取当前页面的宽度
CGFloat x = page.currentPage * self.bounds.size.width;
//通过设置scrollView的偏移量来滚动图像
[self.ADScrollView setContentOffset:CGPointMake(x, 0) animated:YES];
}
现在已经有了可以滚动的数据,和控制页面的pageControl了。只需要设置滚动视图的delegate以及添加定时器控制自动切换页面即可
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
//如果当前页面滑动到第一张(图2),就移动到最后一张(图5)实现右划是最后一张(图4)
if (scrollView.contentOffset.x < self.frame.size.width) {
[self.ADScrollView setContentOffset:CGPointMake(self.frame.size.width * (_imageArray.count + 1), 0) animated:NO];
}
//偏移超过最后一张(图5),将偏移移动到第一张(图1)便于左滑是第一张(图2)
if (scrollView.contentOffset.x > self.frame.size.width * (_imageArray.count + 1)) {
[self.ADScrollView setContentOffset:CGPointMake(self.frame.size.width, 0) animated:NO];
}
//设置当前的pageControl位置
int pageCount = scrollView.contentOffset.x / self.frame.size.width;
//如果当前pageControl位置超出总数,就移到第一张
if (pageCount > _imageArray.count) {
pageCount = 0;
}else if (pageCount == 0){
//如果偏移到最左边就移动到最后一张
pageCount = (int)_imageArray.count - 1;
}else{
pageCount--;
}
self.pageControl.currentPage = pageCount;
}
//开始拖动时
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
//拖动图片的时候,禁止计时器计时
[self.timer invalidate];
}
//结束拖动时
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
//开始计时
[self startTimer];
}
-(void)startTimer {
if (!_duration) {
//如果时间间隔_duration没有设置,就默认定时器3.0秒
self.timer = [NSTimer timerWithTimeInterval:3.0 target:self selector:@selector(updateTimer) userInfo:nil repeats:YES];
}else{
//设置定时器为_duration秒
self.timer = [NSTimer timerWithTimeInterval:_duration target:self selector:@selector(updateTimer) userInfo:nil repeats:YES];
}
//NSRunloop,会使线程的表现变得更加的好,他的存在一个重要目的是当有事件发生时,唤醒线程,当没有事件时,线程将处于休眠状态
//Run loop 在你要和线程有更多的交互时才需要,比如以下情况:
// 使用端口或自定义输入源来和其他线程通信 使用线程的定时器 Cocoa 中使用任何 performSelector...的方法 使线程周期性工作
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}
-(void)updateTimer {
//定时器一到时间就调整当前offset,增加一个滚动视图宽度(就是自动跳转到下一个视图)
CGPoint newOffset = CGPointMake(self.ADScrollView.contentOffset.x + CGRectGetWidth(self.ADScrollView.frame), 0);
[self.ADScrollView setContentOffset:newOffset animated:YES];
}
最后的最后,实现图片的点击事件
#pragma mark - 广告图片点击
- (void)pageViewClick : (UITapGestureRecognizer *)tap {
}
具体就是酱紫,哈哈。记录一下
2015年08月25日09:46:19