Quartz 2D 以及手势的综合 小demo

>
2017总结的动画demo.gif

首先介绍这里面一共有两个比较重要的类

一 、手势工具类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]; 从而重绘图形

  1. 属性:
//
/**填充的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>
  1. 方法
//
/**截图并且返回图片*/
-(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>
  1. 这个方法可以好好看看,规定了上下文中创建切圆的路径并且进行裁切
-(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源码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
提供的源码资源涵盖了python应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
提供的源码资源涵盖了小程序应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值