iOS轮播图广告图

    xiaoxiao2025-12-02  10

    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的头上。

    转载请注明原文地址: https://ju.6miu.com/read-1304525.html
    最新回复(0)