zoukankan      html  css  js  c++  java
  • 第二十一篇、广告轮播器(支持循环滚动)

    1.自定义UIPageControl控件

    .h

    #import <UIKit/UIKit.h>
    
    @protocol CustomPageControlDelegate <NSObject>
    @optional
    - (void) selectedIndex:(NSInteger) index;
    
    @end
    
    @interface CustomPageControl : UIView
    
    @property (nonatomic,assign) NSInteger numberOfPages;
    @property (nonatomic,assign) NSInteger currentPage;
    @property (nonatomic,assign) float PointSize; // 圆点的大小
    @property (nonatomic,assign) float distanceOfPoint; // 两个圆点的距离
    @property (nonatomic,assign) UIColor * currentPagePointColor; // 当前点的颜色
    @property (nonatomic,assign) UIColor * pagePointColor; // 其它圆点的颜色
    @property (nonatomic,strong) UIImage *currentImage; // 当前点的图片
    @property (nonatomic,strong) UIImage *otherImage; // 其它点的图片
    @property (nonatomic,weak) id<CustomPageControlDelegate> delegate;
    
    -(float)sizeForNumberOfPages:(NSInteger)pages;
    -(void)setNumberOfPages:(NSInteger)pages;
    -(void)setCurrentPage:(NSInteger)page;
    
    @end

    .m

    #import "CustomPageControl.h"
    @interface CustomPageControl()
    {
    
    }
    @end
    
    @implementation CustomPageControl
    @synthesize currentPage = _currentPage;
    @synthesize numberOfPages = _numberOfPages;
    
    #pragma mark--系统方法
    - (id) initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            self.backgroundColor = [UIColor clearColor];
        }
        return self;
    }
     - (void) drawRect:(CGRect)rect
    {
        //[super drawRect:rect];
        [self setCurrentPage:0]; // 这个如果不调用(首次加载不能显示,拖动了才显示)
    }
    
    #pragma mark--自定义方法 公有
    -(float)sizeForNumberOfPages:(NSInteger)pages{
        return _distanceOfPoint*(pages+1) + _PointSize*pages;
    }
    
    - (void) setNumberOfPages:(NSInteger)pages
    {
        // 居中
         CGFloat pointImageViewXFloat = (self.frame.size.width -_PointSize * pages - _distanceOfPoint * (pages - 1)) / 2.0;
        for (int i = 0; i < pages; i++) {
           
            UIImageView * pointImageView = [[UIImageView alloc] initWithFrame:CGRectMake(pointImageViewXFloat , (self.frame.size.height-_PointSize)/2.0, _PointSize, _PointSize)];
            
            pointImageView.layer.cornerRadius = _PointSize / 2.0; // 设置半径
            pointImageView.layer.masksToBounds = YES;
            pointImageView.tag = i;
            [self addSubview:pointImageView];
            
            // 添加点击手势
            UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(singleTap:)];
            pointImageView.userInteractionEnabled = YES;
            [pointImageView addGestureRecognizer:tap];
            pointImageViewXFloat +=  _PointSize + _distanceOfPoint ;
        }
    }
    
    
    - (void) setCurrentPage:(NSInteger)page
    {
        NSInteger countOfPages = [self.subviews count];
        for (NSUInteger subviewIndex = 0; subviewIndex < countOfPages; subviewIndex++) {
            UIImageView* subview = [self.subviews objectAtIndex:subviewIndex];
            if (subviewIndex == page) {
                if (_currentImage && _otherImage)
                {
                     subview.image = _currentImage;
                }else
                {
                    [subview setBackgroundColor:_currentPagePointColor];
                }
               
            }else{
                if (_currentImage && _otherImage)
                {
                    subview.image = _otherImage;
                }
                else
                {
                    [subview setBackgroundColor:_pagePointColor];
                }
                
                //subview.image = [UIImage imageNamed:@"point1"];
            }
        }
    }
    #pragma mark--自定义方法 私有
    - (void) singleTap:(UITapGestureRecognizer *) tap
    {
        if ([_delegate respondsToSelector:@selector(selectedIndex:)]) {
            [_delegate selectedIndex:tap.view.tag];
        }
    }
    
    @end

    2.展示图片View

    .h

    #import <UIKit/UIKit.h>
    
    // 用于判断pageControl显示的位置
    typedef enum {
        isCenter, 
        isRight,
    } contentType;
    
    @protocol PictureCycleDelegate <NSObject>
    
    @optional
    /*
     @brief 点击回调
     @param view 当前点击的View
     @param index 当前选择的索引
     */
    -(void) seletedView:(id) view index:(int) index;
    
    @end
    
    @interface PictureCycle : UIView
    
    @property (weak,nonatomic) id<PictureCycleDelegate>delegate;
    
    /*****
     **@param frame 当前view的frame
     **@param picArray 显示的图片数组
     **@param autoBOOL 是否允许自动轮播
     **@param type 去掉pageControl是居中还是居右
     *****/
    - (id)initWithFrame:(CGRect)frame array:(NSMutableArray *)picArray Auto:(BOOL) autoBOOL contentType:(contentType) type; // 根据传入数组来初始化此view
    
    // 移除定时器 ,如果是调用自动轮播,在外面需要调用(不然造成循环引用),不然不调用dealloc
    - (void)removeTimer;
    
    @end

    .m

    //
    //  PictureCircle.m
    //  Circle
    //
    //  Created by egood001 on 15/7/11.
    //  Copyright (c) 2015年 lcy. All rights reserved.
    //
    
    #import "PictureCycle.h"
    #import "CustomPageControl.h"
    #import "MainNewsModel.h"
    #import "BaseNetManager.h"
    
    // 执行动画的时间
    #define animationTime 1.2f
    // 默认的加载图片
    #define defaultImage [UIImage imageNamed:@"zwt"]
    
    @interface PictureCycle ()<UIScrollViewDelegate,CustomPageControlDelegate>
    {
        CGFloat currentWidthFloat;
        CGFloat currentHeightFloat;
        BOOL publicAutoBOOL; // 是否需要自动滚动查看
        contentType modeType;
        CGFloat noteViewHeightFloat;
    }
    
    
    @property (nonatomic, strong) UIScrollView * picScrollView; // 轮播图
    @property (nonatomic, strong) CustomPageControl * pageControl; // 显示条
    @property (nonatomic, strong) NSTimer * timer; // 定时器
    @property (nonatomic, assign) NSInteger totalPicCount; // 总共多少个图片
    
    @property (nonatomic, strong) UIImageView *currentImageView;
    @property (nonatomic, strong) UIImageView *nextImageView;
    @property (nonatomic, strong) UIImageView *onImageView;
    @property (nonatomic, strong) UILabel *messageLaebl;
    
    @property (nonatomic, strong) NSMutableArray *dataArray;
    @property (nonatomic, assign) NSInteger currentPageIndex;
    
    @end
    
    @implementation PictureCycle
    
    #pragma mark--懒加载
    
    -(UIScrollView *) picScrollView
    {
        if (! _picScrollView) {
            _picScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, currentWidthFloat, currentHeightFloat)];
            _picScrollView.showsHorizontalScrollIndicator = NO;
            _picScrollView.showsVerticalScrollIndicator = NO;
            _picScrollView.contentSize = CGSizeMake(3 * currentWidthFloat, 0);
            _picScrollView.contentOffset = CGPointMake(currentWidthFloat, 0);
            _picScrollView.pagingEnabled = YES;
            _picScrollView.delegate = self;
            _picScrollView.scrollEnabled = NO;
            _picScrollView.bounces = NO;
        }
        return _picScrollView;
    }
    
    -(UIImageView *) currentImageView
    {
        if (! _currentImageView) {
            _currentImageView = [[UIImageView alloc]initWithFrame:CGRectMake(currentWidthFloat, 0, currentWidthFloat, currentHeightFloat)];
            _currentImageView.userInteractionEnabled = YES;
            _currentImageView.contentMode = UIViewContentModeScaleToFill;
            
            MainNewsModelList *list = [self.dataArray objectAtIndex:0];
            NSString *imageString = [NSString stringWithFormat:@"%@%@",TestURL,[BaseNetManager getOffRubbishWithString:list.img]];
            NSURL *url = [NSURL URLWithString:imageString];
            [_currentImageView sd_setImageWithURL:url placeholderImage:defaultImage];
            UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap:) ];
            [_currentImageView addGestureRecognizer:tap];
        }
        return _currentImageView;
    }
    
    -(UIImageView *) onImageView
    {
        if (! _onImageView) {
            _onImageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, currentWidthFloat, currentHeightFloat)];
            _onImageView.contentMode = UIViewContentModeScaleToFill;
            _onImageView.userInteractionEnabled = YES;
             NSInteger imageIndex = self.dataArray.count == 1 ? 0 : self.dataArray.count - 1;
            MainNewsModelList *list = [self.dataArray objectAtIndex:imageIndex];
            NSString *imageString = [NSString stringWithFormat:@"%@%@",TestURL,[BaseNetManager getOffRubbishWithString:list.img]];
            NSURL *url = [NSURL URLWithString:imageString];
            [_onImageView sd_setImageWithURL:url placeholderImage:defaultImage];
            UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap:) ];
            [_onImageView addGestureRecognizer:tap];
        }
        return _onImageView;
    }
    
    -(UIImageView *) nextImageView
    {
        if (! _nextImageView) {
            _nextImageView = [[UIImageView alloc]initWithFrame:CGRectMake(2 * currentWidthFloat, 0, currentWidthFloat, currentHeightFloat)];
            _nextImageView.userInteractionEnabled = YES;
            _nextImageView.contentMode = UIViewContentModeScaleToFill;
            NSInteger imageIndex = self.dataArray.count == 1 ? 0 : 1;
            MainNewsModelList *list = [self.dataArray objectAtIndex:imageIndex];
            NSString *imageString = [NSString stringWithFormat:@"%@%@",TestURL,[BaseNetManager getOffRubbishWithString:list.img]];
            NSURL *url = [NSURL URLWithString:imageString];
            [_nextImageView sd_setImageWithURL:url placeholderImage:defaultImage];
            UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap:) ];
            [_nextImageView addGestureRecognizer:tap];
        }
        return _nextImageView;
    }
    
    -(CustomPageControl *) pageControl
    {
        if (! _pageControl) {
            CGFloat width=[UIScreen mainScreen].bounds.size.width;
            float pointSize = 12.0f; // 圆点的大小
            float pointToPointDistantWidth = 3.0f; // 两个圆点的距离
            
            float pageControlWidth = self.dataArray.count * (pointSize + pointToPointDistantWidth) + pointToPointDistantWidth *2;
            float pagecontrolHeight = 10;
            
            // 默认是居右
    //        CGFloat pageControlXFloat = currentWidthFloat - pageControlWidth;
    //        if (modeType == isCenter) {
    //            pageControlXFloat = pageControlXFloat / 2.0;
    //        }
            _pageControl = [[CustomPageControl alloc] initWithFrame:CGRectMake(width/2-pageControlWidth/2, (noteViewHeightFloat - pagecontrolHeight) / 2.0 + 10, pageControlWidth , pagecontrolHeight)];
            _pageControl.PointSize = pointSize;
            _pageControl.distanceOfPoint = pointToPointDistantWidth; // 点与点的距离
            _pageControl.currentPage = 0;
            _pageControl.numberOfPages = self.dataArray.count;
            _pageControl.currentPagePointColor = [UIColor redColor]; // 当前的颜色(还可以设置图片)
            _pageControl.pagePointColor = [UIColor grayColor];
            //[_pageControl setBackgroundColor:[UIColor grayColor]];
        }
        return _pageControl;
    }
    
    #pragma mark--rewrite system Method
    
    /*****
     **@param frame 当前view的frame
     **@param picArray 显示的图片数组
     **@param autoBOOL 是否允许自动轮播
     **@param type 去掉pageControl是居中还是居右
     *****/
    - (id)initWithFrame:(CGRect)frame array:(NSMutableArray *)picArray Auto:(BOOL)autoBOOL contentType:(contentType) type
    {
        self = [super initWithFrame:frame];
        if (self) {
            currentWidthFloat = frame.size.width;
            currentHeightFloat = frame.size.height;
            publicAutoBOOL = autoBOOL;
            modeType = type;
            [self downLoadImages];
            [self setupScrollViewWithArray:picArray];
           // [self emptyDatatoFlag];
        }
        return self;
    }
    
    
    #pragma mark--system Methods
    
    
    - (void) layoutSubviews
    {
        [super layoutSubviews];
    }
    
    - (void)dealloc
    {
        NSLog(@"adDealloc");
    }
    
    #pragma mark--private Methods
    
    /*
     @brief 清除点击的标志
     */
    - (void) emptyDatatoFlag
    {
        [[NSUserDefaults standardUserDefaults] setObject:nil forKey:@"Flag"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
    
    /*
     * @brief 下载图片
     */
    - (void)downLoadImages
    {
        // 1.创建一个组
        dispatch_group_t group = dispatch_group_create();
        
        // MainNewsModelList *list = [self.dataArray objectAtIndex:0];
        for (MainNewsModelList *list in self.dataArray)
        {
            // 将当前的下载操作添加到组中
            dispatch_group_enter(group);
            
            NSString *imageString = [NSString stringWithFormat:@"%@%@",TestURL,[BaseNetManager getOffRubbishWithString:list.img]];
            NSURL *url = [NSURL URLWithString:imageString];
            
            [[SDWebImageManager sharedManager] downloadImageWithURL:url options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
                // 离开当前组
                dispatch_group_leave(group);
            }];
            
        }
        // 2.当所有图片都下载完毕
        dispatch_group_notify(group, dispatch_get_main_queue(), ^{
            
            // 移除所有的子控件
            for (UIView *view in self.subviews) {
                [view removeFromSuperview];
            }
            self.picScrollView = nil;
            self.currentPageIndex = 0;
            [self removeTimer];
            // 重新添加子控件
            [self setupScrollViewWithArray:self.dataArray];
            
        });
        
    }
    
    - (void)setupScrollViewWithArray:(NSMutableArray *)picArray
    {
        // 图片数
        if ( ! [picArray count]) {
            return;
        }
        
        self.dataArray = [NSMutableArray  arrayWithArray:picArray];
        
        NSInteger totalCount = self.dataArray.count;
        self.totalPicCount = totalCount;
        
        // 添加滚动视图
        [self addSubview:self.picScrollView];
        // 添加三张图片
        [_picScrollView addSubview:self.currentImageView];
        [_picScrollView addSubview:self.onImageView];
        [_picScrollView addSubview:self.nextImageView];
    
        
        // 可以在noteView添加titleLable
        UIView *noteView = [[UIView alloc] initWithFrame:CGRectMake(0, currentHeightFloat - 35, currentWidthFloat, 35)];
        noteView.backgroundColor = [UIColor clearColor];
        noteView.alpha = 0.75;
        //[UIColor clearColor];
        noteView.userInteractionEnabled = YES;
        [self addSubview:noteView];
        
        // 设置标题
      //  MainNewsModelList *list = [self.dataArray objectAtIndex:0];
        //UILabel *messageLabel = [[UILabel alloc]init];
        //messageLabel.backgroundColor = [UIColor redColor];
      //  messageLabel.frame = CGRectMake(0, 0, noteView.frame.size.width, noteView.frame.size.height);
       // messageLabel.text = list.title;
        //[noteView addSubview:messageLabel];
        //self.messageLaebl = messageLabel;
        
        noteViewHeightFloat = noteView.frame.size.height;
        
        if(1 < [picArray count])
        {
            if ( publicAutoBOOL ){
               [self addTimer];
            }
            [noteView addSubview:self.pageControl];
            [_picScrollView setScrollEnabled:YES]; // 当图片只有一张,禁止滚动
            
        }
        
    }
    
    // 单击手势监听
    - (void)singleTap:(UITapGestureRecognizer *)tap
    {
        
        if ([_delegate respondsToSelector:@selector(seletedView:index:)]) {
            [_delegate seletedView:tap.view index:(int)self.currentPageIndex];
        }
        
        NSLog(@"当前点击了%@",tap.view);
    
    //    if (publicAutoBOOL)
    //    {
    //        if (self.dataArray.count > 1) { // 如果是轮播的状态,跳转其他页面,停止轮播,返回继续轮播
    //            [self removeTimer];
    //            [self addTimer];
    ////            [[NSUserDefaults standardUserDefaults] setObject:@"1" forKey:@"Flag"];
    ////            [[NSUserDefaults standardUserDefaults] synchronize];
    //        }
    //    }
    
    }
    
    // 添加定时器
    - (void)addTimer
    {
        _timer = [NSTimer scheduledTimerWithTimeInterval:3.5f target:self selector:@selector(nextImage) userInfo:nil repeats:YES];
        NSRunLoop *currentRunLoop = [NSRunLoop currentRunLoop];
        [currentRunLoop addTimer:self.timer forMode:NSRunLoopCommonModes];
    }
    
    // 移除定时器
    - (void)removeTimer
    {
        if (self.timer != nil)
        {
            [self.timer invalidate];
            self.timer = nil;
        }
    }
    
    // 播放下一张图片
    - (void)nextImage
    {
        if (publicAutoBOOL)
        {
            if (self.dataArray.count > 1) {
                    NSString *flagString =[[NSUserDefaults standardUserDefaults] valueForKey:@"Flag"];
                    if ([flagString intValue]) {
                        [self removeTimer];
                        [self addTimer];
                        return;
                    }
            }
        }
        
        CGPoint offset = _picScrollView.contentOffset;
        
        offset.x += self.frame.size.width;
        if (offset.x > self.frame.size.width * 2) {
            offset.x = self.frame.size.width;
        }
        
        [_picScrollView setContentOffset:offset animated:YES];
        
        [self removeTimer];
        [self addTimer];
        
    }
    
    #pragma mark--协议方法
    
    #pragma mark--CostomPageControlDelegate
    - (void) selectedIndex:(NSInteger)index
    {
    
    }
    #pragma mark - scrollViewDelegate
    // 已经拖动
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView
    {
        CGFloat scollViewW = scrollView.frame.size.width;
        CGFloat offsetX = scrollView.contentOffset.x;
        int pageInteger = floor((offsetX - scollViewW / 2) / scollViewW) + 1;
        
        if(pageInteger > 2)
        {
            //防止向右快速滑动出现空白
            CGPoint offset = scrollView.contentOffset;
            offset.x = self.frame.size.width * 2;
            [_picScrollView setContentOffset:offset animated:YES];
            return;
        }
        
        float offset = scrollView.contentOffset.x;
        MainNewsModelList *list;
        if (_nextImageView.image == nil || _onImageView.image == nil) {
            
            //加载下一个视图
            NSInteger imageIndex = self.currentPageIndex >= _dataArray.count - 1 ? 0 : self.currentPageIndex + 1;
            list = [self.dataArray objectAtIndex:imageIndex];
            NSString *imageUrlString = [NSString stringWithFormat:@"%@%@",TestURL,[BaseNetManager getOffRubbishWithString:list.img]];
            NSURL *imageUrl = [NSURL URLWithString:imageUrlString];
            
            [_nextImageView sd_setImageWithURL:imageUrl placeholderImage:defaultImage];
            
            
            //加载上一个视图
            imageIndex = self.currentPageIndex == 0 ? self.dataArray.count - 1 : self.currentPageIndex - 1;
            list = [self.dataArray objectAtIndex:imageIndex];
            imageUrlString = [NSString stringWithFormat:@"%@%@",TestURL,[BaseNetManager getOffRubbishWithString:list.img]];
            imageUrl = [NSURL URLWithString:imageUrlString];
            
            [_onImageView sd_setImageWithURL:imageUrl placeholderImage:defaultImage];
            
        }
        
        if (offset == 0) { // 向左边滑动
            _currentImageView.image = _onImageView.image;
            scrollView.contentOffset = CGPointMake(scrollView.frame.size.width, 0);
            _onImageView.image = nil;
            
            if (self.currentPageIndex == 0) {
                self.currentPageIndex = self.dataArray.count - 1;
            }else{
                self.currentPageIndex -= 1;
            }
            
        }
        
        if (offset == scrollView.frame.size.width * 2) { // 右边滑动
            _currentImageView.image = _nextImageView.image;
            scrollView.contentOffset = CGPointMake(scrollView.frame.size.width, 0);
            _nextImageView.image = nil;
            
            if (self.currentPageIndex == self.dataArray.count - 1) {
                self.currentPageIndex = 0;
            }else{
                self.currentPageIndex += 1;
            }
            
        }
        
        [UIView animateWithDuration:0.3f animations:^{
                _pageControl.currentPage = self.currentPageIndex ;
            }];
    
        list = [self.dataArray objectAtIndex:self.currentPageIndex];
        self.messageLaebl.text = list.title;
    }
    
    // 将要拖动
    - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
    {
        if (publicAutoBOOL) {
            if (self.dataArray.count > 1) {
                //[self emptyDatatoFlag];
                [self removeTimer];
            }
        }
    }
    
    // 拖动完成
    - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
    {
        if (publicAutoBOOL) {
            if (self.dataArray.count > 1) {
                [self addTimer];
            }
        }
    }
    
    
    
    
    @end
  • 相关阅读:
    九度 1363 欢乐斗地主
    九度 1377 缓变序列
    九度 1376 最近零子序列
    转几篇关于linux下AT&T汇编的帖子
    九度 1358 陈博的平均主义
    九度 1394 五连击数组
    HDU 2817 A sequence of numbers
    HDU 1867 A + B for you again
    HDU 1753 大明A+B
    HDU 1715 大菲波数
  • 原文地址:https://www.cnblogs.com/HJQ2016/p/5818300.html
Copyright © 2011-2022 走看看