Quartz 2D 以及手势的综合 小demo
来源:互联网 发布:在淘宝上搜血滴子 编辑:程序博客网 时间:2024/05/15 15:34
>
首先介绍这里面一共有两个比较重要的类
一 、手势工具类LYPGestureRecognizerTool.h
大体思路
1 . 由于是手势工具类,所以在以后用的时候,可能回多次创建,所以索性就弄了一个单利类。
static id _instancetype;+(instancetype) sharedGestureRecognizerTool { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instancetype = [[self alloc]init]; }); return _instancetype;}
2 . 每个手势的添加都是利用类方法,向外部暴露了一个UIView接口
///** * 传入View 给view添加捏合手势 * view: 手势将被添加到这个view上 * isSupportMoreGesture 表示是否支持多手势 * pinchiBlock: 点击事件的回调 * isGestureRecognizerStateEnded: 手势是否结束 * pinch: 手势对象 */+(void)pinchWithView: (UIView *)view andPinchBlock: (void(^)(BOOL isGestureRecognizerStateEnded,UIPinchGestureRecognizer *pinch))pinchiBlock;/** * 传入view,给View,添加点击手势 * view: 手势将被添加到这个view上 * isSupportMoreGesture 表示是否支持多手势 * numberOfTouches: 设置触控对象的个数(几个手指) * numberOfTaps: 点击次数 * selectorBlock: 点击事件的回调 */+(void)tapWithView: (UIView *)view andNumberOfTouches: (NSInteger)numberOfTouches andNumberOfTaps: (NSInteger)numberOfTaps andSelectorBlock:(void(^)(UITapGestureRecognizer *tap))selectorBlock;/** * 传入view,给View,添加拖动手势 * view: 手势将被添加到这个view上 * isSupportMoreGesture 表示是否支持多手势 * panGesture: 点击事件的回调 */+(void)panWithView: (UIView *)view andPanBlock: (void(^)(UIPanGestureRecognizer *panGesture))panBlock;/** * 传入view,给View,添加旋转手势 * view: 手势将被添加到这个view上 * isSupportMoreGesture 表示是否支持多手势 * rotationGesture: 点击事件的回调 */+(void)rotationWithView: (UIView *)view andRotationBlock: (void(^)(CGFloat rotation,UIRotationGestureRecognizer *rotationGesture))rotationBlock;/** * 传入view,给View,添加轻扫手势 * view: 手势将被添加到这个view上 * isSupportMoreGesture 表示是否支持多手势 * direction: 轻扫的方向 * swipeBlock: 事件的回调 */+(void)swipeWithView: (UIView *)view andSwipeGrestureDirection: (UISwipeGestureRecognizerDirection)direction andSwipeBlock: (void(^)(UISwipeGestureRecognizer *swipe))swipeBlock;````3 . 手势事件的回调都是利用了block,如果外部没有对block进行赋值,那么将执行相应的手势事件相应. 每个手势事件都对应着声明了一个纯私有block属性,从而保证了事件的传递````<div class="se-preview-section-delimiter"></div>#import "LYPGestureRecognizerTool.h"@interface LYPGestureRecognizerTool() <UIGestureRecognizerDelegate>//tap(点击手势)回调的block@property (nonatomic,copy) void(^tapBlock)(UITapGestureRecognizer *tap);//pinch(捏合手势)回调的block@property (nonatomic,copy) void(^pinchBlock)(BOOL isEnd,UIPinchGestureRecognizer *pinch);//pan(拖动手势)回调的block@property (nonatomic,copy) void(^panBlock)(UIPanGestureRecognizer *pan);//longPress(长按手势)回调的block@property (nonatomic,copy) void(^longPressBlock)();//rotation(旋转手势)回调的block@property (nonatomic,copy) void(^rotationBlock)(CGFloat rotation,UIRotationGestureRecognizer *rotationGesture);//swipe (清扫手势) 回调的block@property (nonatomic,copy) void(^swipeBlock)(UISwipeGestureRecognizer *swipe);@end<div class="se-preview-section-delimiter"></div>
4 . 默认手势事件的相应举例:
1. pinch的创建
1. 首先创建(获取)了一个手势工具类,然后在设置代理,(这里的代理设置主要是因为解决手势冲突)
2. 给View添加手势
3. self.panBlock = panBlock;(储存外部传过来的block代码块)
实现pan手势事件
2. pinch手势事件的实现
1.判断,外部的panBlock有没有实现,有就执行,没有就执行默认的相应事件;
+(void)panWithView: (UIView *)view andPanBlock: (void(^)(UIPanGestureRecognizer *panGesture))panBlock { LYPGestureRecognizerTool *gestureTool = [self sharedGestureRecognizerTool]; view.userInteractionEnabled = YES; UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:gestureTool action:@selector(pan:)]; pan.delegate = gestureTool; gestureTool.panBlock = panBlock; [view addGestureRecognizer:pan];}//拖动事件的相应事件-(void)pan: (UIPanGestureRecognizer *)pan { //视图前置操作 [pan.view.superview bringSubviewToFront:pan.view]; if (self.panBlock) { self.panBlock(pan); return; } CGPoint center = pan.view.center; CGFloat cornerRadius = pan.view.frame.size.width / 2; UIWindow *window = [UIApplication sharedApplication].keyWindow; //位置获取偏移点的位置 CGPoint translation = [pan translationInView:window]; //NSLog(@"%@",[NSValue valueWithCGPoint:translation]); //NSLog(@"%--------@",[NSValue valueWithCGPoint:center]); pan.view.center = CGPointMake(center.x + translation.x, center.y + translation.y); CGPoint velocity = [pan velocityInView:window]; //NSLog(@"------%@",[NSValue valueWithCGPoint:velocity]); //重设偏移量 [pan setTranslation:CGPointZero inView:window];}<div class="se-preview-section-delimiter"></div>
二、 RoundView View裁切类
他可以控制每个角的切圆半径,从而更加灵活,并且可以传入image,进行切割,并且读取切割后的image;
大体思路
1.提供两个构造方法(类构造方法,对象构造方法)
//MARK: - 实例化方法+(instancetype) roundViewWithIsCut: (BOOL)isCut andCutRadius: (CGFloat)radius andImage: (UIImage *)image{ return [[self alloc]initWithIsCut:isCut andCutRadius:radius andImage:image];}-(instancetype) initWithIsCut: (BOOL)isCut andCutRadius: (CGFloat)radius andImage: (UIImage *)image { if (self = [super init]) { //先走这句话,是因为现在的isCut是NO,不会切圆,如果先设置isCut那么radius是nil那么就会使View被切成圆形 self.radius = radius; self.isCut = isCut; self.image = image; } return self;}<div class="se-preview-section-delimiter"></div>
2.传入简单的几个属性参数,并对自己的属性赋值,而每个属性赋值的时候都会调用 [self setNeedsDisplay]; 从而重绘图形
- 属性:
///**填充的image*/@property (nonatomic,strong) UIImage *image;/**裁切后的image*/@property (nonatomic,strong) UIImage *cutImage;/**是否裁切,默认NO*/@property (nonatomic,assign) BOOL isCut;/**裁切的位置及范围*/@property (nonatomic,assign) CGRect cutRect;/**圆形的半径*/@property (nonatomic,assign) CGFloat radius;/**四个角的半径控制接口*/@property (nonatomic,assign) CGFloat leftTopRadiu;@property (nonatomic,assign) CGFloat leftBottomRadiu;@property (nonatomic,assign) CGFloat rightTopRadiu;@property (nonatomic,assign) CGFloat rightBottonRadiu;/**图片的透明度*/@property (nonatomic,assign) CGFloat alpha;<div class="se-preview-section-delimiter"></div>
- 方法
///**截图并且返回图片*/-(UIImage *)snapshotImage;/** * 综合的改变渲染参数(如果改变多个参数后渲染,建议用此方法) */-(void) imageChengeLeftTopRadiu: (CGFloat)leftTopRadiu andLeftBottomRadiu: (CGFloat)leftBottomRadiu andRightTopRadiu: (CGFloat)rightTopRadiu andRightBottomRadiu: (CGFloat)rightBottomRadiu andCutRect: (CGRect) cutRect andImageAlpha: (CGFloat)alpha;<div class="se-preview-section-delimiter"></div>
- 这个方法可以好好看看,规定了上下文中创建切圆的路径并且进行裁切
-(void)contextRefWithcontext: (CGContextRef)context { CGFloat minx = CGRectGetMinX(self.cutRect),//矩形中最小的x midx = CGRectGetMidX(self.cutRect),//矩形中最大x值的一半 maxx = CGRectGetMaxX(self.cutRect);//矩形中最大的x值 CGFloat miny = CGRectGetMinY(self.cutRect),//矩形中最小的Y值 midy = CGRectGetMidY(self.cutRect),//矩形中最大Y值的一半 maxy = CGRectGetMaxY(self.cutRect);//矩形中最大的Y值 CGContextMoveToPoint(context, minx, midy);//从点A 开始 //从点A到点B再从点B到点C形成夹角进行切圆 CGContextAddArcToPoint(context, minx, miny, midx, miny, self.radius + self.leftTopRadiu); CGContextAddArcToPoint(context, maxx, miny, maxx, midy, self.radius + self.rightTopRadiu); CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, self.radius + self.rightBottonRadiu); CGContextAddArcToPoint(context, minx, maxy, minx, midy, self.radius + self.leftBottomRadiu); CGContextClosePath(context); //裁切 CGContextClip(context);}
三动画的实现
大体思路
利用了displayLink 计时器
还有别忘了调用 [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
把它加入到Runloop的common标记的modes中
对于(Runloop的学习总结请看这里)
好了暂时就这么多了,一切请看github源码
三动画的实现
大体思路
利用了displayLink 计时器
还有别忘了调用 [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
把它加入到Runloop的common标记的modes中
对于(Runloop的学习总结请看这里)
好了暂时就这么多了,一切请看github源码
- Quartz 2D 以及手势的综合 小demo
- Quartz 2D 以及手势的综合 小demo
- 一个手势图案解锁的小demo
- UI进阶第十发:Quartz 2D手势识别
- Quartz 2D之手势解锁(支付宝)
- ios手势的综合
- Quartz 2D的坐标系和UIKit的坐标系对比以及相互转换
- Quartz 2D的坐标系和UIKit的坐标系对比以及相互转换
- Quartz 2D的坐标系和UIKit的坐标系对比以及相互转换 ? 赶驴记
- Quartz的Demo
- Quartz 2D的路径的使用
- 手势识别以及语音识别demo
- Quartz 2D 相关的知识
- Quartz 2D的简单使用
- Quartz 2D简单的绘图
- Quartz 2D基本图形的绘制
- Quartz 2D中UIImage的分类
- Quartz 2D绘图的一般步骤
- 44. Wildcard Matching
- win10并盘问题
- 45. Jump Game II
- 46. Permutations
- 47. Permutations II
- Quartz 2D 以及手势的综合 小demo
- 48. Rotate Image
- SpringBoot开发详解(一)--初识SpringBoot
- 如何在Github Pages搭建自己写的页面?
- 移动开发框架 Weex 简介大会观点
- python中的编码问题
- NimGame292
- 什么是感恩
- Maven安装与Myeclipes环境变量搭建