iOS开发系列之常用自定义控件开发集—自动广告墙图片控件开发

来源:互联网 发布:java自行车是哪个国家 编辑:程序博客网 时间:2024/05/21 10:11

现在很多app都有自动切换图片展示功能尤其是视频播放器,电商app,今天我给大家开发一个这样常用的组件,该控件是纯手工打造,自己实现触摸控制没有用UIScrollView,下面是实现原理:创建三个UIImageView控件通过触摸切换该种方式节省内存,当用户要展示100张图片时也只会创建三个UIImageView控件。
WHC_AdvertisingWall.h 头文件代码如下:

////  WHC_AdvertisingWall.h//  WHC_AdvertisingWall////  Created by 吴海超 on 15/3/24.//  Copyright (c) 2015年 吴海超. All rights reserved.//#import <UIKit/UIKit.h>@class WHC_AdvertisingWall;//单击图片代理@protocol WHC_AdvertisingWallDelegate <NSObject>@optional- (void)WHC_AdvertisingWall:(WHC_AdvertisingWall*)whc_AdWallView clickImage:(UIImage*)image index:(NSInteger)index;@end@interface WHC_AdvertisingWall : UIView@property (nonatomic,assign) BOOL  isCanTouchScroll;@property (nonatomic,assign) BOOL  isCanAutoScroll;@property (nonatomic,assign) id<WHC_AdvertisingWallDelegate> delegate;//以图片对象数组进行初始化- (instancetype)initWithFrame:(CGRect)frame withImages:(NSArray*)imageArr;- //以图片名称数组进行初始化- (instancetype)initWithFrame:(CGRect)frame withImageNames:(NSArray *)imageNames;- //以图片对象重载图片- (void)reloadImage:(NSArray*)images;- //以图片名称重载图片- (void)reloadImageNames:(NSArray*)imageNames;@end

WHC_AdvertisingWall.m源文件实现原理:

////  WHC_AdvertisingWall.m//  WHC_AdvertisingWall////  Created by 吴海超 on 15/3/24.//  Copyright (c) 2015年 吴海超. All rights reserved.//#import "WHC_AdvertisingWall.h"#define KWHC_MOVE_IMAGE_DURING (0.4)           //动画切换图片周期#define KWHC_LEFT_START_INDEX (1)              //向左切换时的初始imageView下标#define KWHC_RIGHT_START_INDEX (0)             //向右切换时的初始imageView下标#define KWHC_PAGE_CONTROL_HEIGHT (20.0)        //页控件高度//方向枚举typedef enum {    NONE,    LEFT,    RIGHT}WHC_TOUCH_ORI;@interface WHC_AdvertisingWall (){    NSArray                 * _imageArr;              //图片数组    NSMutableArray          * _imageViewArr;          //图片控件数组    UIPageControl           * _pageCtl;               //页控件    NSTimer                 * _timer;                 //定时器    UIPanGestureRecognizer  * _panGesture;            //触摸手势    CGRect                    _frame;                 //该控件frame    NSInteger                 _currentIndex;          //当前图片下标    CGPoint                   _startPoint;            //触摸开始点    WHC_TOUCH_ORI             _currentMoveOri;        //当前移动方向    BOOL                      _isStartTouch;          //是否开始触摸了}@end@implementation WHC_AdvertisingWall#pragma mark - init- (instancetype)initWithFrame:(CGRect)frame withImages:(NSArray*)imageArr{    self = [super initWithFrame:frame];    if(self != nil){        _currentIndex = 0;        _currentMoveOri = NONE;        _frame = frame;        _imageArr = [NSArray arrayWithArray:imageArr];        _imageViewArr = [NSMutableArray array];        //注册触摸事件        [self registerTouchEvent];        //初始化ui布局        [self initLayout];    }    return self;}- (instancetype)initWithFrame:(CGRect)frame withImageNames:(NSArray *)imageNames{    NSMutableArray  * images = [NSMutableArray array];    for (NSString * imagePath in imageNames) {        [images addObject:[UIImage imageNamed:imagePath]];    }    return [self initWithFrame:frame withImages:images];}#pragma mark - controlAnimation//设置是否可以触摸切换- (void)setIsCanTouchScroll:(BOOL)isCanTouchScroll{    _isCanTouchScroll = isCanTouchScroll;    if(!isCanTouchScroll){        [self removeGestureRecognizer:_panGesture];    }else{        [self addGestureRecognizer:_panGesture];    }}//设置是否可以自动切换- (void)setIsCanAutoScroll:(BOOL)isCanAutoScroll{    _isCanAutoScroll = isCanAutoScroll;    if(isCanAutoScroll){        if(_timer != nil){            [_timer invalidate];            _timer = nil;        }        _timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(startAutoScrollImage) userInfo:nil repeats:YES];    }else{        [_timer invalidate];        _timer = nil;    }}//开始自动切换- (void)startAutoScrollImage{    //default to left scroll image    [self animationMoveImage:KWHC_LEFT_START_INDEX withOri:LEFT];}#pragma mark - other//加载错误提示view- (void)loadAlertText{    UILabel  * labText = [[UILabel alloc]initWithFrame:CGRectMake(0.0, .0, CGRectGetWidth(_frame), CGRectGetHeight(_frame))];    labText.backgroundColor = [UIColor clearColor];    labText.textColor = [UIColor grayColor];    labText.textAlignment = NSTextAlignmentCenter;    labText.numberOfLines = 0;    labText.text = @"WHC_AdvertisingWall\nimage count = 0";    [self addSubview:labText];}- (void)registerTouchEvent{    _panGesture = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handlePanGesture:)];}#pragma mark - reload//重新载入图片(image对象)- (void)reloadImage:(NSArray*)images{    for (UIView * view in self.subviews) {        [view removeFromSuperview];    }    self.isCanTouchScroll = NO;    self.isCanAutoScroll = NO;    _currentIndex = 0;    _currentMoveOri = NONE;    [_imageViewArr removeAllObjects];    _imageArr = nil;    _imageArr = [NSArray arrayWithArray:images];    [self initLayout];}//重新载入图片(image name对象)- (void)reloadImageNames:(NSArray*)imageNames{    NSMutableArray  * images = [NSMutableArray array];    for (NSString * imagePath in imageNames) {        [images addObject:[UIImage imageNamed:imagePath]];    }    [self reloadImage:images];}#pragma mark - initUI- (void)initLayout{    NSInteger  imageCount = _imageArr.count;    if(imageCount < 1){        [self loadAlertText];        return;    }    for (int i = 0; i < 3; i++) {        UIImageView  * imageView = [[UIImageView alloc]initWithFrame:CGRectMake((i - 1) * CGRectGetWidth(_frame), 0.0, CGRectGetWidth(_frame), CGRectGetHeight(_frame))];        imageView.tag = i;        if(i == 1){            imageView.image = _imageArr[0];        }else if(i == 0){            imageView.image = _imageArr[imageCount - 1];        }else{            NSInteger  index = i >= imageCount ? imageCount - 1 : i - 1;            imageView.image = _imageArr[index];        }        [self addSubview:imageView];        [_imageViewArr addObject:imageView];    }    _pageCtl = [[UIPageControl alloc]initWithFrame:CGRectMake(0.0, CGRectGetHeight(_frame) - KWHC_PAGE_CONTROL_HEIGHT, CGRectGetWidth(_frame), KWHC_PAGE_CONTROL_HEIGHT)];    _pageCtl.backgroundColor = [UIColor clearColor];    _pageCtl.numberOfPages = imageCount;    [self addSubview:_pageCtl];    UIButton * clearBtn = [UIButton buttonWithType:UIButtonTypeCustom];    clearBtn.frame = CGRectMake(.0, .0, CGRectGetWidth(_frame), CGRectGetHeight(_frame));    clearBtn.backgroundColor = [UIColor clearColor];    [clearBtn addTarget:self action:@selector(clickClearBtn:) forControlEvents:UIControlEventTouchUpInside];    [self addSubview:clearBtn];    if(imageCount > 1){        self.isCanTouchScroll = YES;        self.isCanAutoScroll = YES;    }}#pragma mark - handleAnimation//手势触摸移动图片- (void)touchMoveImage:(NSInteger)index withDistance:(CGFloat)moveXDistace{    for (NSInteger i = index; i < index + 2 ; i++) {        //移动图片        CGPoint  currImageViewCenter = ((UIImageView *)_imageViewArr[i]).center;        ((UIImageView *)_imageViewArr[i]).center = CGPointMake(currImageViewCenter.x + moveXDistace, currImageViewCenter.y);    }}//动画切换图片- (void)animationMoveImage:(NSInteger)index withOri:(WHC_TOUCH_ORI)touchOri{    self.isCanTouchScroll = NO;    [UIView animateWithDuration:KWHC_MOVE_IMAGE_DURING animations:^{        //移动图片        for (NSInteger i = index; i < index + 2; i++) {            UIImageView * imageView = (UIImageView *)_imageViewArr[i];            CGFloat distanceX = CGRectGetWidth(_frame) / 2.0;            if(touchOri == LEFT){                distanceX = -distanceX;                imageView.center = CGPointMake((i - 1) * CGRectGetWidth(_frame) + distanceX , imageView.center.y);            }else{                imageView.center = CGPointMake(i * CGRectGetWidth(_frame) + distanceX , imageView.center.y);            }        }    } completion:^(BOOL finished) {        //动态交换图片控件数组位子        if(touchOri == LEFT){            _currentIndex++;            if(_currentIndex >= _imageArr.count){                _currentIndex = 0;            }            [_imageViewArr exchangeObjectAtIndex:0 withObjectAtIndex:1];            [_imageViewArr exchangeObjectAtIndex:1 withObjectAtIndex:2];        }else{            _currentIndex--;            if(_currentIndex < 0){                _currentIndex = _imageArr.count - 1;            }            [_imageViewArr exchangeObjectAtIndex:0 withObjectAtIndex:2];            [_imageViewArr exchangeObjectAtIndex:1 withObjectAtIndex:2];        }        //设置页控件当前页        _pageCtl.currentPage = _currentIndex;        for(int i = 0; i < _imageViewArr.count; i++){            //刷新切换后新或者旧图片显示            UIImageView * imageView  = _imageViewArr[i];            imageView.center = CGPointMake( i * CGRectGetWidth(_frame) - CGRectGetWidth(_frame) / 2.0, imageView.center.y);            if(i == 0){                NSInteger index = _currentIndex - 1;                if(index < 0){                    index = _imageArr.count - 1;                }                imageView.image = _imageArr[index];            }else if(i == 1){                imageView.image = _imageArr[_currentIndex];            }else{                NSInteger index = _currentIndex + 1;                if(index >= _imageArr.count){                    index = 0;                }                imageView.image = _imageArr[index];            }        }        self.isCanTouchScroll = YES;    }];}//动画恢复切换状态(手势移动距离不满足条件需要恢复初始状态)- (void)animationResetImage:(NSInteger)index  withOri:(WHC_TOUCH_ORI)touchOri{    if(touchOri == LEFT){        index = 1;  //向左恢复初始下标    }else{        index = 0;  //向右恢复初始下标    }    [UIView animateWithDuration:KWHC_MOVE_IMAGE_DURING animations:^{        for (NSInteger i = index; i < 2 + index; i++) {            UIImageView * imageView = (UIImageView *)_imageViewArr[i];            CGFloat distanceX = CGRectGetWidth(_frame) / 2.0;            if(touchOri == LEFT){                imageView.center = CGPointMake(distanceX + (i - 1) * distanceX * 2.0, imageView.center.y);            }else{                imageView.center = CGPointMake(-distanceX + i * distanceX * 2.0, imageView.center.y);            }        }    }];}#pragma mark - handleGesture//触摸手势处理- (void)handlePanGesture:(UIPanGestureRecognizer *)panGesture{    switch (panGesture.state) {        case UIGestureRecognizerStateBegan:            if(self.isCanAutoScroll){                _isStartTouch = YES;                self.isCanAutoScroll = NO;            }            _startPoint = [panGesture locationInView:self];            break;        case UIGestureRecognizerStateChanged:{            CGPoint  currentPoint = [panGesture locationInView:self];            CGFloat  moveXInstance = currentPoint.x - _startPoint.x;            if([panGesture velocityInView:self].x < 0){                //left                if (_currentMoveOri == RIGHT) {                    [self touchMoveImage:KWHC_RIGHT_START_INDEX withDistance:-fabsf(moveXInstance)];                }else{                    _currentMoveOri = LEFT;                    [self touchMoveImage:KWHC_LEFT_START_INDEX withDistance:-fabsf(moveXInstance)];                }            }else{                //right                if(_currentMoveOri == LEFT){                    [self touchMoveImage:KWHC_LEFT_START_INDEX withDistance:fabsf(moveXInstance)];                }else{                    _currentMoveOri = RIGHT;                    [self touchMoveImage:KWHC_RIGHT_START_INDEX withDistance:fabsf(moveXInstance)];                }            }            _startPoint = currentPoint;        }            break;        case UIGestureRecognizerStateEnded:        case UIGestureRecognizerStateCancelled:{            UIImageView * imageView = _imageViewArr[1];            if(imageView.center.x <= 0){                [self animationMoveImage:KWHC_LEFT_START_INDEX withOri:LEFT];            }else if(imageView.center.x >= CGRectGetWidth(_frame)){                [self animationMoveImage:KWHC_RIGHT_START_INDEX withOri:RIGHT];            }else{                [self animationResetImage:KWHC_RIGHT_START_INDEX withOri:_currentMoveOri];            }            _currentMoveOri = NONE;            if(_isStartTouch){                self.isCanAutoScroll = YES;            }            _isStartTouch = NO;        }            break;        default:            break;    }}#pragma mark - clickAction//单击图片调用- (void)clickClearBtn:(UIButton*)sender{    if(_currentIndex <= _imageArr.count - 1){        if(_delegate && [_delegate respondsToSelector:@selector(WHC_AdvertisingWall:clickImage:index:)]){            [_delegate WHC_AdvertisingWall:self clickImage:_imageArr[_currentIndex] index:_currentIndex];        }    }}@end

运行效果图:
这里写图片描述
WHC_AdvertisingWallDemo下载

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 唱美声总夹嗓子怎么办 发财树树干出褶怎么办 月季花夏天换盆出现黄叶怎么办 刚种的月季枯了怎么办 新买的月季黄叶了怎么办 月季花叶孑轰发黄怎么办? 新种的月季苗弱怎么办? 月季换盆后浇透水叶子黄了怎么办 肉肉移栽后浇透水怎么办 月季花扦插的没长根发芽了怎么办 君子兰发的小苗怎么办 蔷薇光长枝条不开花怎么办 牡丹发芽又干了怎么办 擦皮炎平后皮肤变黑怎么办 误喝发霉的咖啡渣怎么办 狗吃了速溶咖啡怎么办 咖啡机放豆的地方进水怎么办 干吃咖啡粉上瘾怎么办 去良友花艺住宿怎么办 充气娃娃放了气怎么办 煮杜鹃根没有锅怎么办 淘宝店卖鲜花被买家拒收货怎么办 执业医师电子注册忘记密码怎么办 怀孕吃了油炸的怎么办 百合长得太高怎么办 百合的杆没了怎么办 百合花长得太细怎么办 沙漠玫瑰的花苞打不开怎么办 鲜切花 较小的花苞怎么办 大棚玫瑰苗水大涝的不长怎么办 鲜花买回来蔫了怎么办 喝玫瑰醋上火了怎么办 插在花泥上的花怎么办 插的花蔫了怎么办 紫睡莲的茎软了怎么办 家养的荷花烂叶怎么办 家养的荷花叶老是枯萎怎么办 新买的绣球蔫了怎么办 绣球花被太阳晒阉了怎么办 羊肉香精放多了怎么办 被飞机防腐剂弄到皮肤怎么办