用CollectionView封装一个广告视图

suiling 2016-10-17 08:34:49 2388

前言

相信很多初学iOS的朋友一开始都会学到如何用ScrollView做一个可以循环播放的广告视图, 一般来说,要做一个可以逐页逐页滚动的广告视图,可以通过在ScrollView上水平连续添加多个ImageView来实现。 但是如果在要播放的广告图片太多的情况下, 这种方法会导致需要创建多个ImageView, 占用内存。但是使用CollectionView来做就完全不同了,在这里我分享一个用CollectionView做的广告视图(名为KHAdView), 代码放在Github上, 使用说明也有中英版的,各位朋友有需自取哈。GitHub代码

效果图

在进行说明前先放上效果图给大家看看,其实也就是一般的广告视图,精华都在代码里, 强烈建议去github下载源代码来看 

()

使用CollectionView的好处

  • 利用UICollectionView的复用机制,系统最多只会创建两个CollectionViewCell, 也就是说系统最多只会创建两个ImageView, 在这种情况下,我们就可以做到用两个ImageView满足播放无限张图片的需求,大大减小了对内存的损耗!

  • 可以同时使用UICollectionViewDelegate 和 UIScrollViewDelegate,方便操作和监听不同的事件

KHAdView的特点

  • 支持双向循环滚动

  • 可自定义广告视图

  • 既可以加载URL也可以加载本地文件

如何使用KHAdView

  1. 下载并复制KHAdView文件夹下的源代码到你的工程目录。

  2. 初始化KHAdView,并为其赋值一个Frame

    KHAdView *view = [[KHAdView alloc]initWithFrame:CGRectMake(0, 0, kScreen_Width, KHAdView_Height)];self.tableView.tableHeaderView = view;

    当然,你也可以通过Auto Layout来设置它的大小和位置

  3. 使用“setDataSource: WithSourceType:”方法给KHAdView添加数据源,通过SourceType来指定加载的数据源是URL还是本地文件。

    [self.khAdView setDataSource:_urlArr WithSourceType:KHSourceInternetType];
  4. 开启定时器,让广告视图循环滚动。

    [self.khAdView startTimer];

    到此你就成功添加了一个高性能的广告视图!

自定义还可以得到新的效果

()

如何自定义:

  1. 改变控件的颜色

    • 改变底部背景栏的颜色,默认是黑色

      self.khAdView.bottomViewColor = [UIColor redColor];
    • 改变PageControl的指示颜色,默认是白色

      self.khAdView.pageIndicatorTintColor = [UIColor yellowColor];
    • 改变当前页PageControl的指示颜色,默认是红色

      self.khAdView.currentPageIndicatorTintColor = [UIColor blackColor];
  2. 改变底部背景栏的高度,默认是30

    self.khAdView.bottomViewHeight = 50;
  3. 改变底部背景栏的透明度,默认是0.3

    self.khAdView.alpha = 1.0;
  4. 改变定时器的时间间隔,默认是2

    self.khAdView.timeInterval = 1.f;
  5. 改变广告视图的滚动方向,默认是从右向左滚动

    self.khAdView.direction = KHScrollDirectionFromLeft;
  6. 隐藏底部背景栏和页码指示器,默认不隐藏

    self.khAdView.hideBottomView = YES;self.khAdView.hidePageControl = YES;

核心代码

如何实现循环滚动

所谓的循环滚动,其实只是一个假象。假如有ABC三张图片需要展示, 要实现循环,只需要拷贝头尾两张图片,并添加到ABC三张图片的首尾,形成CABCA的图片结构。 接下来就是关键了,当图片按照如下顺序滚动A-->B-->C-->A连续滚动,我们就可以在其中一个方向上看到循环滚动了。 最后,我们还需要用scrollViewDidScroll这个代理方法来监听当前正在展示的是第几张图片,如果是第二张A图片,这个时候我们就要调用方法,让CollectionView偷偷地(不带动画效果)Scroll到第一张A图片,这一步也是最“狡诈”的一步。另一个方向的循环滚动也是同理可得。这段核心代码如下:

- (void)setDataSource:(NSArray *)dataSource WithSourceType:(KHSourceType)sourceType{
    _dataSource = dataSource;
    self.images = [NSMutableArray array];
    NSInteger count = dataSource.count + 2;
    
    for (NSInteger i = 0; i < count; i++) {
        UIImage *image = nil;
        switch (sourceType) {
            case KHSourceInternetType:
                if (0 == i) {
                    image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[dataSource lastObject]]]];
                }else if(count - 1 == i){
                    image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[dataSource firstObject]]]];
                }else{
                    image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:dataSource[i - 1]]]];
                }
                [self.images addObject:image];
                break;
                
            default:
                if (0 == i) {
                    image = [UIImage imageNamed:[dataSource lastObject]];
                }else if(count - 1 == i){
                   image = [UIImage imageNamed:[dataSource firstObject]];
                }else{
                    image = [UIImage imageNamed:dataSource[i - 1]];
                }
                [self.images addObject:image];
                break;
        }
    }
    
    [self.collectionView reloadData];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    NSInteger currentPage = (scrollView.contentOffset.x / CGRectGetWidth(self.frame)) - 1;
    self.pageControl.currentPage = currentPage;
    
    if (currentPage < 0)
    {
        self.pageControl.currentPage = self.dataSource.count - 1;
        [self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:self.dataSource.count inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
        return;
    }
    else if (currentPage == self.dataSource.count)
    {
        self.pageControl.currentPage = 0;
        [self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:1 inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
        return;
    }
}

结语

展示的代码只是一部分,有兴趣的朋友欢迎去我的github下载相应的代码和Demo。当然,觉得好用可以fork回去放在以后的项目中用,如果觉得好用不妨给我在GitHub上点个星星 :P。 最后,本人学iOS时间不长, 还算初学者,如果觉得代码哪里有问题,欢迎心平气和地来给我建议。


文章来自Arron_Zhang的投稿,原文地址