iOS开发系列之常用自定义控件开发集—自动3D广告墙图片控件开发
来源:互联网 发布:淘宝数据的uv是什么 编辑:程序博客网 时间:2024/05/21 21:45
这节课我们根据上一节课的自动广告墙图片控件版本进行升级改进为3D效果上一节课的代码链接
下面是3D自动广告墙实现代码版本如下:
WHC_3DAdvertisingWall.h头文件如下:
//// WHC_3DAdvertisingWall.h// WHC_3DAdvertisingWall//// Created by 吴海超 on 15/3/26.// Copyright (c) 2015年 吴海超. All rights reserved.//#import <UIKit/UIKit.h>@class WHC_3DAdvertisingWall;//单击图片代理@protocol WHC_3DAdvertisingWallDelegate <NSObject>@optional- (void)WHC_3DAdvertisingWall:(WHC_3DAdvertisingWall*)whc_AdWallView clickImage:(UIImage*)image index:(NSInteger)index;@end@interface WHC_3DAdvertisingWall : UIView@property (nonatomic,assign) id<WHC_3DAdvertisingWallDelegate>delegate;@property (nonatomic,assign) BOOL isCanTouchScroll;@property (nonatomic,assign) BOOL isCanAutoScroll;//以图片对象数组初始化- (instancetype)initWithFrame:(CGRect)frame withImages:(NSArray*)imageArr;//以图片名称数组初始化- (instancetype)initWithFrame:(CGRect)frame withImageNames:(NSArray *)imageNames;//以图片对象数组重载图片- (void)reloadImage:(NSArray*)images;//以图片名称数组重载图片- (void)reloadImageNames:(NSArray*)imageNames;@end
WHC_3DAdvertisingWall.m源文件如下:
//// WHC_3DAdvertisingWall.m// WHC_3DAdvertisingWall//// Created by 吴海超 on 15/3/26.// Copyright (c) 2015年 吴海超. All rights reserved.//#import "WHC_3DAdvertisingWall.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) //页控件高度#define KWHC_3D_WIDTH (50.0) //3D效果UIImageView的宽度#define KWHC_DISZ (-1.0 / 900.0) //3D透视参数#define KWHC_EXEC_DISTANCE (18.0) //进行切换图片有效像素距离#define KWHC_HIDE_DISTANCE (6.0) //进行移动图片隐藏有效像素距离//自定义方向枚举typedef enum { NONE, LEFT, RIGHT}WHC_TOUCH_ORI;@interface WHC_3DImageView : UIImageView@property (nonatomic,assign)CGFloat hideCenterX; //存储隐藏时中心点x坐标@property (nonatomic,assign)WHC_TOUCH_ORI ori; //存储触摸方向- (void)reset; //恢复初始参数的状态@end@implementation WHC_3DImageView- (void)reset{ self.hidden = NO; _hideCenterX = 0.0; _ori = NONE;}@end@interface WHC_3DAdvertisingWall (){ NSArray * _imageArr; //图片数组 NSMutableArray * _imageViewArr; //图片控件数组 UIPageControl * _pageCtl; //页控件 NSTimer * _timer; //定时器 UIPanGestureRecognizer * _panGesture; //触摸手势 CGRect _frame; //该控件frame NSInteger _currentIndex; //当前图片下标 CGPoint _startPoint; //触摸开始点 WHC_TOUCH_ORI _currentMoveOri; //当前移动方向 BOOL _isStartTouch; //是否开始触摸了 BOOL _isExecAnimation; //是否执行切换动画}@end@implementation WHC_3DAdvertisingWall#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 WHC_3DImageView * imageView0 = _imageViewArr[0]; [UIView animateWithDuration:0.1 animations:^{ imageView0.center = CGPointMake(0.0, imageView0.center.y); imageView0.layer.transform = [self initMakeTransform3D:M_PI / 2.0]; } completion:^(BOOL finished) { imageView0.layer.transform = [self initMakeTransform3D:-M_PI / 2.0]; imageView0.center = CGPointMake(CGRectGetWidth(_frame), imageView0.center.y); [self updateImageViewImage:LEFT]; [self animationResetImage:0 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_3DAdvertisingWall\nimage count = 0"; [self addSubview:labText];}- (void)registerTouchEvent{ _panGesture = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handlePanGesture:)];}#pragma mark - reload//重新加载图片以图片对象数组- (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];}//重新加载图片以图片名称数组- (void)reloadImageNames:(NSArray*)imageNames{ NSMutableArray * images = [NSMutableArray array]; for (NSString * imagePath in imageNames) { [images addObject:[UIImage imageNamed:imagePath]]; } [self reloadImage:images];}#pragma mark - makeTransform3D//3D处理- (CATransform3D)initMakeTransform3D:(CGFloat)angle{ CGPoint center = CGPointZero; CATransform3D rotate = CATransform3DMakeRotation(angle, 0.0, 1.0, 0.0); CATransform3D transform3DToCenter = CATransform3DMakeTranslation(-center.x, -center.y, 0.0); CATransform3D transform3DToBack = CATransform3DMakeTranslation(center.x, center.y, 0.0); CATransform3D scale = CATransform3DIdentity; scale.m34 = KWHC_DISZ; return CATransform3DConcat(rotate , CATransform3DConcat(CATransform3DConcat(transform3DToCenter, scale), transform3DToBack));}//设置图片控件3d效果- (void)setImageViewTransform3D:(WHC_3DImageView*)imageView angle:(CGFloat)angle distance:(CGFloat)distance ori:(WHC_TOUCH_ORI)ori{ CATransform3D rotate = CATransform3DRotate(imageView.layer.transform, angle, 0.0, 1.0, 0.0); imageView.center = CGPointMake(imageView.center.x + distance, imageView.center.y); imageView.layer.transform = rotate; if((imageView.center.x <= KWHC_HIDE_DISTANCE && ori == LEFT) || (imageView.center.x >= (CGRectGetWidth(_frame) - KWHC_HIDE_DISTANCE) && ori == RIGHT)){ if(!imageView.hidden){ imageView.hidden = YES; imageView.ori = ori; imageView.hideCenterX = imageView.center.x; } }else{ if(ori == LEFT && imageView.tag == 2){ CGFloat centerX = imageView.center.x; if(CGRectGetWidth(_frame) - centerX - cosf(rotate.m13) * (CGRectGetWidth(imageView.frame) / 2.0) >= KWHC_EXEC_DISTANCE){ if(_isExecAnimation)return; [self animationMoveImage:0 withOri:ori]; } }else if(ori == RIGHT && imageView.tag == 0){ CGFloat centerX = imageView.center.x; if(centerX - cosf(rotate.m31) * (CGRectGetWidth(imageView.frame) / 2.0) >= KWHC_EXEC_DISTANCE){ if(_isExecAnimation)return; [self animationMoveImage:0 withOri:ori]; } } if(imageView.hidden && imageView.ori != ori){ if((ori == LEFT && imageView.center.x < imageView.hideCenterX) || (ori == RIGHT && imageView.center.x > imageView.hideCenterX)){ [imageView reset]; } } }}#pragma mark - initUI//初始化ui布局- (void)initLayout{ NSInteger imageCount = _imageArr.count; if(imageCount < 1){ [self loadAlertText]; return; } CGFloat imageWidth = CGRectGetWidth(_frame) - KWHC_3D_WIDTH * 2.0; for (int i = 0; i < 3; i++) { WHC_3DImageView * imageView = [[WHC_3DImageView alloc]initWithFrame:CGRectMake((i - 1) * imageWidth + KWHC_3D_WIDTH, 0.0, imageWidth, CGRectGetHeight(_frame))]; imageView.tag = i; if(i == 1){ imageView.image = _imageArr[0]; imageView.layer.transform = [self initMakeTransform3D:0.0]; }else if(i == 0){ imageView.center = CGPointMake(KWHC_3D_WIDTH / 2.0, imageView.center.y); imageView.image = _imageArr[imageCount - 1]; imageView.layer.transform = [self initMakeTransform3D:acosf(KWHC_3D_WIDTH / imageWidth)]; }else{ imageView.center = CGPointMake(imageWidth + KWHC_3D_WIDTH + KWHC_3D_WIDTH / 2.0, imageView.center.y); NSInteger index = i >= imageCount ? imageCount - 1 : i - 1; imageView.image = _imageArr[index]; imageView.layer.transform = [self initMakeTransform3D:-acosf(KWHC_3D_WIDTH / imageWidth)]; } [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)updateImageViewImage:(WHC_TOUCH_ORI)touchOri{ 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++){ WHC_3DImageView * imageView = _imageViewArr[i]; imageView.tag = i; 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]; } }}//触摸移动图片- (void)touchMoveImage:(WHC_TOUCH_ORI)ori withDistance:(CGFloat)moveXDistace{ CGFloat imageWidth = CGRectGetWidth([UIScreen mainScreen].bounds) - KWHC_3D_WIDTH * 2.0; CGFloat angle = (moveXDistace / ((KWHC_3D_WIDTH / 2.0) + imageWidth)) * 2.0 * acosf((KWHC_3D_WIDTH / imageWidth)); for (int i = 0; i < 3; i++) { WHC_3DImageView * imageView = _imageViewArr[i]; [self setImageViewTransform3D:imageView angle:-angle distance:moveXDistace ori:ori]; }}//动画移动图片- (void)animationMoveImage:(NSInteger)index withOri:(WHC_TOUCH_ORI)touchOri{ WHC_3DImageView * imageView0 = _imageViewArr[0]; WHC_3DImageView * imageView2 = _imageViewArr[2]; if(touchOri == LEFT){ [imageView0 reset]; imageView0.layer.transform = [self initMakeTransform3D:-M_PI / 2.0]; imageView0.center = CGPointMake(CGRectGetWidth(_frame), imageView0.center.y); }else if(touchOri == RIGHT){ [imageView2 reset]; imageView2.layer.transform = [self initMakeTransform3D:M_PI / 2.0]; imageView2.center = CGPointMake(0.0, imageView2.center.y); } [self updateImageViewImage:touchOri]; [self updateImageViewPosition];}//更新图片空间位子- (void)updateImageViewPosition{ CGFloat imageWidth = CGRectGetWidth(_frame) - KWHC_3D_WIDTH * 2.0; WHC_3DImageView * imageView0 = _imageViewArr[0]; WHC_3DImageView * imageView1 = _imageViewArr[1]; WHC_3DImageView * imageView2 = _imageViewArr[2]; [imageView0 reset]; [imageView1 reset]; [imageView2 reset]; imageView0.center = CGPointMake(KWHC_3D_WIDTH / 2.0, imageView0.center.y); imageView0.layer.transform = [self initMakeTransform3D:acosf(KWHC_3D_WIDTH / imageWidth)]; imageView1.center = CGPointMake(CGRectGetWidth(_frame) / 2.0,imageView1.center.y); imageView1.layer.transform = [self initMakeTransform3D:0.0]; imageView2.center = CGPointMake(CGRectGetWidth(_frame) - KWHC_3D_WIDTH / 2.0, imageView2.center.y); imageView2.layer.transform = [self initMakeTransform3D:-acosf(KWHC_3D_WIDTH / imageWidth)];#if 0 [UIView animateWithDuration:KWHC_MOVE_IMAGE_DURING animations:^{ imageView0.center = CGPointMake(KWHC_3D_WIDTH / 2.0, imageView0.center.y); imageView0.layer.transform = [self initMakeTransform3D:acosf(KWHC_3D_WIDTH / imageWidth)]; imageView1.center = CGPointMake(CGRectGetWidth(_frame) / 2.0,imageView1.center.y); imageView1.layer.transform = [self initMakeTransform3D:0.0]; imageView2.center = CGPointMake(CGRectGetWidth(_frame) - KWHC_3D_WIDTH / 2.0, imageView2.center.y); imageView2.layer.transform = [self initMakeTransform3D:-acosf(KWHC_3D_WIDTH / imageWidth)]; }completion:^(BOOL finished) { _isExecAnimation = NO; self.isCanTouchScroll = YES; }];#endif}//动画调整图片位子- (void)animationResetImage:(NSInteger)index withOri:(WHC_TOUCH_ORI)touchOri{ CGFloat imageWidth = CGRectGetWidth(_frame) - KWHC_3D_WIDTH * 2.0; WHC_3DImageView * imageView0 = _imageViewArr[0]; WHC_3DImageView * imageView1 = _imageViewArr[1]; WHC_3DImageView * imageView2 = _imageViewArr[2]; if(imageView0.hidden){ imageView0.center = CGPointMake(0.0, imageView0.center.y); imageView0.layer.transform = [self initMakeTransform3D:M_PI / 2.0]; } if(imageView2.hidden){ imageView2.center = CGPointMake(CGRectGetWidth(_frame), imageView2.center.y); imageView2.layer.transform = [self initMakeTransform3D:-M_PI / 2.0]; } [imageView0 reset]; [imageView1 reset]; [imageView2 reset]; _isExecAnimation = YES; self.isCanTouchScroll = NO; [UIView animateWithDuration:KWHC_MOVE_IMAGE_DURING animations:^{ imageView0.center = CGPointMake(KWHC_3D_WIDTH / 2.0, imageView0.center.y); imageView0.layer.transform = [self initMakeTransform3D:acosf(KWHC_3D_WIDTH / imageWidth)]; imageView1.center = CGPointMake(CGRectGetWidth(_frame) / 2.0,imageView1.center.y); imageView1.layer.transform = [self initMakeTransform3D:0.0]; imageView2.center = CGPointMake(CGRectGetWidth(_frame) - KWHC_3D_WIDTH / 2.0, imageView2.center.y); imageView2.layer.transform = [self initMakeTransform3D:-acosf(KWHC_3D_WIDTH / imageWidth)]; }completion:^(BOOL finished) { _isExecAnimation = NO; self.isCanTouchScroll = YES; }];}#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:{ if(_isExecAnimation) return; CGPoint currentPoint = [panGesture locationInView:self]; CGFloat moveXInstance = currentPoint.x - _startPoint.x; if([panGesture velocityInView:self].x < 0){ //left if (_currentMoveOri == RIGHT) { [self touchMoveImage:LEFT withDistance:-fabsf(moveXInstance)]; }else{ _currentMoveOri = LEFT; [self touchMoveImage:LEFT withDistance:-fabsf(moveXInstance)]; } }else{ //right if(_currentMoveOri == LEFT){ [self touchMoveImage:RIGHT withDistance:fabsf(moveXInstance)]; }else{ _currentMoveOri = RIGHT; [self touchMoveImage:RIGHT withDistance:fabsf(moveXInstance)]; } } _startPoint = currentPoint; } break; case UIGestureRecognizerStateEnded: case UIGestureRecognizerStateCancelled:{ _currentMoveOri = NONE; if(_isStartTouch){ self.isCanAutoScroll = YES; } _isStartTouch = NO; [self animationResetImage:KWHC_RIGHT_START_INDEX withOri:_currentMoveOri]; } break; default: break; }}#pragma mark - clickAction//单击图片处理- (void)clickClearBtn:(UIButton*)sender{ if(_currentIndex <= _imageArr.count - 1){ if(_delegate && [_delegate respondsToSelector:@selector(WHC_3DAdvertisingWall:clickImage:index:)]){ [_delegate WHC_3DAdvertisingWall:self clickImage:_imageArr[_currentIndex] index:_currentIndex]; } }}@end
WHC_3DAdvertisingWallDemo下载
0 0
- iOS开发系列之常用自定义控件开发集—自动3D广告墙图片控件开发
- iOS开发系列之常用自定义控件开发集—自动广告墙图片控件开发
- 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自动清除控件
- Spring mvc详解 (下)
- SQL必知必会 笔记 第二十一章 使用游标
- Graphic Architecture
- MFC中头文件和预定义宏
- 下载Android源代码错误汇总分析
- iOS开发系列之常用自定义控件开发集—自动3D广告墙图片控件开发
- Android采用opensl-es录音
- linux 下rtc驱动分析
- Java中Comparable和Comparator实现对象比较
- BAT 参数去引号方法大全
- UVA10202Pairsumonious Numbers
- 安卓中Activity的onStart()和onResume()的区别是什么
- 第四章 Apk包测试用例编写
- CRM 常用的一些JavaScript