iOS 自动循环播放广告控件实现

清华大佬耗费三个月吐血整理的几百G的资源,免费分享!....>>>

摘要 iOS下实现的一个简单的循环播放小广告的控件,为了节约内存,使用三个imageview来实现

1.原理:图片:图片集合名称保存成array;     

           轮播:为了实现滑动效果,至少需要三个imageview,为了确保左右滑动,需要一直显示中间的view

           每次滑动后都需要重新加载三个view的图片。并设置当前图片下标

2.接口:提供给viewcontroller一个判断左右滑动的接口,并实现滑动效果

            提供给pagecontroller一个设置页面的接口,根据下标设置当前现实页

3.代码:ADScrollView,附详细注释

.h

@interface ADScrollView : UIScrollView {
    NSTimer *_timer;
}

@property (nonatomic, retain) NSMutableArray *ads;          // 图集

@property (nonatomic, retain) NSMutableArray *images;       // 视图集合(三个视图,左中右)

@property (nonatomic, assign) NSUInteger nowImageIndex;     // 当前图片下表
@property (nonatomic, assign) CGPoint         curPoint;     // 当前视图坐标

- (void)changeToImage:(NSUInteger)index;                    // 改变到某个广告,当我们点击pagecontrol的某个页时,将页号作为参数窜过来,即可实现效果

// 滑动后,将最后的坐标点传过来,即可判断是左滑还是右滑,并实现滑动效果
// 返回1:右滑   -1:左滑    0:未滑动
- (NSInteger)scrollToPoint:(CGPoint)point;

@end

.m

@implementation ADScrollView

- (void)dealloc {
    // 关闭定时器并释放
    [_timer invalidate];
    _timer = nil;
}

- (id)init {
    self = [super init];
    if (self) {
        self.ads = [NSMutableArray arrayWithObjects:@"ad01.png", @"ad02.png", @"ad03.jpg", nil];
        
        // scroll的分页设置
        self.pagingEnabled = YES;
        self.showsHorizontalScrollIndicator = NO;
        self.showsVerticalScrollIndicator = NO;
        self.contentSize = CGSizeMake(3 * 320, 100.0);
        
        NSInteger kCount = [_ads count];
        self.images = [[NSMutableArray alloc] initWithCapacity:3];
        // 初始化三个切换页
        for (int i = 0; i < 3; i++) {
            UIImageView *view = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[_ads objectAtIndex:(i+kCount-1)%kCount]]];
            view.frame = CGRectMake(i*320, 0, 320, 100);
            [self addSubview:view];
            [self.images addObject:view];
        }
        _nowImageIndex = 0;
        self.bounds = CGRectMake(320, 0, 320, 100);
        _curPoint = self.bounds.origin;   // 当前左上角坐标
        
        // 初始化定时器
        _timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(scrollTimer) userInfo:nil repeats:YES];
        //self.adDelegate = nil;
    }
    return self;
}

#pragma mark - 定时器
- (void)scrollTimer {
    // 自动播放
    [self scrollRectToVisible:CGRectMake(640, 0, 320, 100) animated:YES];
}

#pragma mark - 设置显示第几页
- (void)changeToImage:(NSUInteger)index {
    _nowImageIndex = index;         // 当前视图下标切换过去
    
    // 设置三个view的显示
    self.bounds = CGRectMake(320, 0, 320, 100);
    ((UIImageView *)[self.images objectAtIndex:2]).image = [UIImage imageNamed:[self.ads objectAtIndex:[self getImageNext]]];     // 加载下一张视图
    ((UIImageView *)[self.images objectAtIndex:1]).image = [UIImage imageNamed:[self.ads objectAtIndex:_nowImageIndex]];     // 加载当前窗口视图
    ((UIImageView *)[self.images objectAtIndex:0]).image = [UIImage imageNamed:[self.ads objectAtIndex:[self getImagePre]]];     // 加载上一个窗口视图
}

#pragma mark - 判断左滑 右滑 实现滑动效果
- (NSInteger)scrollToPoint:(CGPoint)point {
    NSInteger dictionary = 0;
    if (point.x-_curPoint.x == 320.0 || point.x-_curPoint.x == -640.0) {  // 右滑
        _nowImageIndex = [self getImageNext];    // 获取当前图片下标
        dictionary = 1;
    }
    else if (0 != point.x - _curPoint.x){       // 左滑
        _nowImageIndex = [self getImagePre];    // 获取当前图片下标
        dictionary = -1;
    }
    
    // 始终显示的是中间视图,只不过各个视图加载的图片变了
    self.bounds = CGRectMake(320, 0, 320, 100);
    ((UIImageView *)[self.images objectAtIndex:2]).image = [UIImage imageNamed:[self.ads objectAtIndex:[self getImageNext]]];     // 加载下一张视图
    ((UIImageView *)[self.images objectAtIndex:1]).image = [UIImage imageNamed:[self.ads objectAtIndex:_nowImageIndex]];     // 加载当前窗口视图
    ((UIImageView *)[self.images objectAtIndex:0]).image = [UIImage imageNamed:[self.ads objectAtIndex:[self getImagePre]]];     // 加载上一个窗口视图
    
    return dictionary;       // 如果是右滑  返回yes  左滑返回no
}

#pragma mark - 获取图片下标
- (NSInteger)getImageNext {
    if (_nowImageIndex == [_ads count] - 1) {
        return 0;
    }
    return _nowImageIndex + 1;
}

- (NSInteger)getImagePre {
    if (0 == _nowImageIndex) {
        return [_ads count]-1;
    }
    return _nowImageIndex-1;
}

@end

ViewController需要设置ADScrollView的委托,并实现两个方法

// scrollview 滑动结束,响应手势滑动处理
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    NSInteger dic = [_adScroll scrollToPoint:scrollView.bounds.origin];
    if (1 == dic) {     // 右滑
        _page.currentPage = (_page.currentPage+1)%_page.numberOfPages;
    }
    else if (-1 == dic){  // 左滑
        _page.currentPage = (_page.currentPage+_page.numberOfPages-1)%_page.numberOfPages;
    }
}

// scrollview动作结束,响应自动轮播方式处理
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
    NSInteger dic = [_adScroll scrollToPoint:scrollView.bounds.origin];
    if (1 == dic) {     // 右滑
        _page.currentPage = (_page.currentPage+1)%_page.numberOfPages;
    }
    else if (-1 == dic){  // 左滑
        _page.currentPage = (_page.currentPage+_page.numberOfPages-1)%_page.numberOfPages;
    }
}

// uipageControl的响应方法
- (void)scrolTimer:(NSInteger)dictionary {
    if (1 == dictionary) {
        _page.currentPage = (_page.currentPage+_page.numberOfPages+1)%_page.numberOfPages;
    }
    else if(-1 == dictionary) {
        _page.currentPage = (_page.currentPage+_page.numberOfPages-1)%_page.numberOfPages;
    }
    NSLog(@"%@",_adScroll);
}

ps:只需要这些设置就可以实现广告的轮播了,

对于广告的大小可以根据实际情况自己改,

我这个是320*100的尺寸