您的位置:首页 > 移动开发 > IOS开发

iOS轮播图广告图

2016-01-06 19:57 330 查看
iOS界面上经常见到无限轮播图,n张图片轮流播放。

下面给出一个解决方案和demo(https://github.com/zhengwenming/WMBannerView)。

demo可设定轮播时间,可轮播本地和网络图片(可设置默认的placeholder),支持手动和自动无限循环轮播。



思路是这样的,我们做一个WMBannerView继承UIView,给出初始化方法,

-(instancetype)initWithFrame:(CGRect)frame withURLArrayOrImagesArray:(NSArray *)dataArray;

这个初始化方法会传进去一个数组,这个数组里面可以放本地的UIImage对象,也可以放网络上图片的URL。这个WMBannerView里面有一个UIScrollView,用这个UIScrollView去不断的加载上中下这三个imageView。到达最后一个iamge的时候,再滑动就加载第一个,如果反过来滑动到第一个图片,再滑动,就加载最后一个ImageView。具体的看代码实现。

.h文件里的代码:

#import < UIKit/UIKit.h>

typedef NS_ENUM(NSInteger,WMPageContolAlignment) {

WMPageContolAlignmentCenter, /*< 滚动点居中 /

/* */

WMPageContolAlignmentRight, /*< 滚动点居右 /

/* */

WMPageContolAlignmentNone /*< 滚动点隐藏 /

};

typedef void(^TapActionBlock)(NSInteger index);

@interface WMBannerView : UIView

/* 播放周期,默认五秒钟 如设置0则不播放 */

@property(nonatomic,assign)NSTimeInterval animationDuration;

/* 滚动点对齐方式,默认居中 */

@property(nonatomic,assign)WMPageContolAlignment pageControlAlignment;

/* 默认图片,下载未完成时显示 网络图片的时候设置*/

/* 注意:赋值必须写在Start方法之前,否则仍然为nil */

@property(nonatomic,strong)UIImage *placeHoldImage;

/* 数据源 **/

@property(nonatomic,copy)NSArray *dataArray;

/**

* 初始化广告播放滚动View

*

* @param rect 尺寸位置

* @param dataArray 图片数据源

*/

-(instancetype)initWithFrame:(CGRect)frame withURLArrayOrImagesArray:(NSArray *)dataArray;

/**

* 开始播放,默认五秒钟,点击响应block回调

*

* @param block 回调,返回当前图片index,不需要回调则设置为nil

*/

- (void)startWithTapActionBlock:(TapActionBlock)block;

/**

* 停止播放

*/

- (void)stop;

@end

再看.m实现文件里面的代码

依赖库为SDWebImage

#import “UIImageView+WebCache.h”

#import “WMBannerView.h”

@interface WMBannerView ()

//容器

@property(nonatomic,strong)UIScrollView *scrollView;

/* 滚动圆点 **/

@property(nonatomic,strong)UIPageControl *pageControl;

/* 定时器 **/

@property(nonatomic,strong)NSTimer *animationTimer;

/* 当前index **/

@property(nonatomic,assign)NSInteger currentPageIndex;

/* 所有的图片数组 **/

@property(nonatomic,strong)NSMutableArray *imageArray;

/* 当前图片数组,永远只存储三张图 **/

@property(nonatomic,strong)NSMutableArray *currentArray;

/* block方式接收回调 */

@property(nonatomic,copy)TapActionBlock block;

@end

@implementation WMBannerView

-(instancetype)initWithFrame:(CGRect)frame withURLArrayOrImagesArray:(NSArray *)dataArray{

self = [super initWithFrame:frame];

if (self) {

self.dataArray = dataArray;

self.autoresizesSubviews = YES;

self.scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];

self.scrollView.contentMode = UIViewContentModeCenter;

self.scrollView.contentSize = CGSizeMake(3 *frame.size.width, frame.size.height);

self.scrollView.delegate = self;

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

self.scrollView.pagingEnabled = YES;

self.scrollView.showsHorizontalScrollIndicator = NO;

self.scrollView.showsVerticalScrollIndicator = NO;

[self addSubview:self.scrollView];

//设置分页显示的圆点
_pageControl = [[UIPageControl alloc] init];
_pageControl.alpha = 0.8;
_pageControl.currentPageIndicatorTintColor = [UIColor redColor];
_pageControl.pageIndicatorTintColor = [UIColor whiteColor];
[self addSubview:_pageControl];

//点击事件
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap)];
[self addGestureRecognizer:tapGesture];

//默认五秒钟循环播放
self.animationDuration = 5;
//默认居中
self.pageContolAliment = WMPageContolAlignmentCenter;
//默认第一张
self.currentPageIndex = 0;
}
return self;


}

-(void)layoutSubviews{

[super layoutSubviews];

self.scrollView.frame = self.bounds;

}

-(void)setPageContolAliment:(WMPageContolAlignment)pageContolAliment{

_pageControlAlignment = pageContolAliment;

_pageControl.hidden = NO;

switch (pageContolAliment) {

case WMPageContolAlignmentCenter:

{

_pageControl.frame = CGRectMake(0, CGRectGetHeight(self.scrollView.frame) - 20, CGRectGetWidth(self.scrollView.frame), 10);

}

break;

case WMPageContolAlignmentRight:

{

CGSize size = CGSizeMake(self.dataArray.count * 10 * 1.2, 10);

CGFloat x = self.scrollView.frame.size.width - size.width - 10;

CGFloat y = self.scrollView.frame.size.height - 20;

_pageControl.frame = CGRectMake(x, y, size.width, size.height);

}

break;

case WMPageContolAlignmentNone:

_pageControl.hidden = YES;

break;

default:
break;
}


}

-(void)setAnimationDuration:(NSTimeInterval)animationDuration{

_animationDuration = animationDuration;

[self.animationTimer invalidate];
self.animationTimer = nil;

if (animationDuration <= 0) {
return;
}

self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:_animationDuration
target:self
selector:@selector(animationTimerDidFired:)
userInfo:nil
repeats:YES];

[self.animationTimer setFireDate:[NSDate distantFuture]];


}

-(void)downLoadImage{

if (self.dataArray && self.dataArray.count > 0) {

if ([self.dataArray.firstObject respondsToSelector:@selector(hasPrefix:)]) {

if ([self.dataArray.firstObject hasPrefix:@”http”]) {//网络图片

self.imageArray = [NSMutableArray array];

__weak typeof(self) weak = self;

[self.dataArray enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

UIImageView *imageView = [[UIImageView alloc]initWithFrame:self.scrollView.frame];

[imageView sd_setImageWithURL:[NSURL URLWithString:obj] placeholderImage:self.placeHoldImage];

[weak.imageArray addObject:imageView];

}];

_pageControl.numberOfPages = self.dataArray.count;

[self configContentViews];

}
}
else{//本地图片
self.imageArray = [NSMutableArray array];
__weak typeof(self) weak = self;
[self.dataArray enumerateObjectsUsingBlock:^(UIImage *  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
UIImageView *imageView = [[UIImageView alloc]initWithFrame:self.scrollView.frame];
imageView.image = obj;
[weak.imageArray addObject:imageView];
}];
_pageControl.numberOfPages = self.dataArray.count;
[self configContentViews];
}
}


}

#pragma mark - 私有函数

(void)configContentViews

{

[self.scrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];

NSInteger previousPageIndex = [self getValidNextPageIndexWithPageIndex:_currentPageIndex - 1];

NSInteger rearPageIndex = [self getValidNextPageIndexWithPageIndex:_currentPageIndex + 1];

self.currentArray = (_currentArray?:[NSMutableArray new]);

_currentArray.count == 0 ?:[_currentArray removeAllObjects];

if (_imageArray) {

if (_imageArray.count >= 3) {

[_currentArray addObject:_imageArray[previousPageIndex]];

[_currentArray addObject:_imageArray[_currentPageIndex]];

[_currentArray addObject:_imageArray[rearPageIndex]];

}

else{

[self getImageFromArray:_imageArray[previousPageIndex]];

[self getImageFromArray:_imageArray[_currentPageIndex]];

[self getImageFromArray:_imageArray[rearPageIndex]];

}

}

[_currentArray enumerateObjectsUsingBlock:^(UIImageView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

obj.userInteractionEnabled = YES;

CGRect rightRect = obj.frame;

rightRect.origin = CGPointMake(CGRectGetWidth(self.frame) * idx, 0);

obj.frame = rightRect;

[self.scrollView addSubview:obj];

}];

[self.scrollView setContentOffset:CGPointMake(CGRectGetWidth(self.scrollView.frame), 0)];

}

(NSInteger)getValidNextPageIndexWithPageIndex:(NSInteger)currentPageIndex;

{

if(currentPageIndex == -1){

return self.dataArray.count - 1;

}

else if (currentPageIndex == self.dataArray.count){

return 0;

}

else

return currentPageIndex;

}

/**

* 解决小于三个图片显示的bug

* @param imageView 原始图

*/

-(void)getImageFromArray:(UIImageView *)imageView{

//开辟自动释放池

@autoreleasepool {

UIImageView *tempImage = [[UIImageView alloc]initWithFrame:imageView.frame];

tempImage.image = imageView.image;

[_currentArray addObject:tempImage];

}

}

#pragma mark - UIScrollViewDelegate


(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView

{

[self.animationTimer setFireDate:[NSDate distantFuture]];

}

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

{

[self.animationTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow:self.animationDuration]];

}

(void)scrollViewDidScroll:(UIScrollView *)scrollView

{

int contentOffsetX = scrollView.contentOffset.x;

if(contentOffsetX >= (2 * CGRectGetWidth(scrollView.frame))) {

self.currentPageIndex = [self getValidNextPageIndexWithPageIndex:self.currentPageIndex + 1];

_pageControl.currentPage = _currentPageIndex;

[self configContentViews];

}

if(contentOffsetX <= 0) {

self.currentPageIndex = [self getValidNextPageIndexWithPageIndex:self.currentPageIndex - 1];

_pageControl.currentPage = _currentPageIndex;

[self configContentViews];

}

}

(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView

{

[scrollView setContentOffset:CGPointMake(CGRectGetWidth(scrollView.frame), 0) animated:YES];

}

pragma mark - 循环事件

(void)animationTimerDidFired:(NSTimer *)timer

{

CGPoint newOffset = CGPointMake(self.scrollView.contentOffset.x + CGRectGetWidth(self.scrollView.frame), self.scrollView.contentOffset.y);

[self.scrollView setContentOffset:newOffset animated:YES];

}

pragma mark - 响应事件

(void)tap

{

if (self.block) {

self.block(self.currentPageIndex);

}

}

pragma mark - 开始滚动

-(void)startWithTapActionBlock:(TapActionBlock)block{

[self.animationTimer setFireDate:[NSDate date]];

[self downLoadImage];

self.block = block;

}

pragma mark - 停止滚动

-(void)stop{

[self.animationTimer invalidate];

}

(void)dealloc

{

self.animationTimer = nil;

self.imageArray = nil;

self.dataArray = nil;

self.scrollView = nil;

}

@end

用法

那么做好我们的轮播图WMBannerView了,现在开始用了

/*

网络图片测试

*/

NSArray *URLArray = @[@”http://farm2.staticflickr.com/1709/24157242566_98d0192315_m.jpg“,

@”http://farm2.staticflickr.com/1715/23815656639_ef86cf1498_m.jpg“,

@”http://farm2.staticflickr.com/1455/23888379640_edf9fce919_m.jpg“];

WMBannerView * wmView = [[WMBannerView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.width*3/4) withURLArrayOrImagesArray:URLArray];

wmView.pageControlAlignment = WMPageContolAlignmentCenter;

wmView.placeHoldImage = [UIImage imageNamed:@”placeholderImage”];

wmView.animationDuration = 1.0;//设置滚动的时间间隔,为0的时候不自动滚动

//点击图片的回调block,可以知道点击的index

[wmView startWithTapActionBlock:^(NSInteger index) {

NSLog(@”点击了第%@张”,@(index));

}];

然后放置到tableView的tableHeaderView上面

table = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) style:UITableViewStylePlain];

table.dataSource = self;

table.delegate = self;

table.tableHeaderView = wmView;

table.tableFooterView = [UIView new];

[self.view addSubview:table];

Demo地址

https://github.com/zhengwenming/WMBannerView

描述:强大的广告轮播图,可设定轮播时间,可轮播本地和网络图片(可设置默认的placeholder),支持手动和自动无限循环轮播。可放到UITableView头上,也可以放置到UICollectionView的头上。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: