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
- iOS开发系列之常用自定义控件开发集—自动广告墙图片控件开发
- iOS开发系列之常用自定义控件开发集—自动3D广告墙图片控件开发
- iOS开发系列之常用自定义控件开发集—自定义数字键盘控件开发
- iOS开发系列之常用自定义控件开发集—自定义对话框(UIAlertView)控件开发
- iOS开发系列之常用自定义控件开发集—自定义UIPickerView控件开发2
- iOS开发系列之常用自定义控件开发集—自定义UIDatePicker控件开发
- iOS开发系列之常用自定义控件开发集—自定义组按钮控件开发
- iOS开发系列之常用自定义控件开发集—自定义下拉列表按钮控件开发
- iOS开发系列之常用自定义控件开发集—自定义状态栏消息提示控件开发
- iOS开发系列之常用自定义控件开发集—Android的Toast控件开发
- iOS开发系列之常用自定义控件开发集—进度条Loading控件开发
- iOS开发系列之常用自定义控件开发集—自定义单选按钮或者多选按钮控件开发
- iOS开发系列之常用自定义控件开发集—自定义UITableViewCell侧滑菜单控件开发
- iOS开发系列之常用自定义控件开发集—继承UIButton控件代码快速创建按钮开发
- IOS开发--自定义控件
- IOS开发--自定义控件
- ios 开发常用控件
- android 开发进阶 自定义控件-仿ios自动清除控件
- java网络编程入门教程
- 找出重复次数最多的数字
- CentOS 6.5 下安装 Redis 2.8.7
- 批处教程 for /f 中的Delims和Tokens总结
- Android学习笔记(5)——保存文件到sd卡
- iOS开发系列之常用自定义控件开发集—自动广告墙图片控件开发
- Memcahed 命令操作
- TDP(TCP-over-UDP library):基于UDP协议之上实现
- 删除SQL2008日志
- PageRank算法简介及Map-Reduce实现
- iOS开发规范
- ubuntu windows互传文件、samba服务器搭起
- enumerate学习
- ubifs[ubi文件系统]