博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
计算Pan手势到指定点的角度
阅读量:7050 次
发布时间:2019-06-28

本文共 4874 字,大约阅读时间需要 16 分钟。

计算Pan手势到指定点的角度

 

效果图:

源码:

////  RootViewController.m//  Circle////  Copyright (c) 2014年 Y.X. All rights reserved.//#import "RootViewController.h"#import "Radian.h"#import "FrameAccessor.h"@interface RootViewController ()@property (nonatomic, strong) CALayer *layer;@end@implementation RootViewController- (void)viewDidLoad{    [super viewDidLoad];    // 显示参考用的view    UIView *showView = [[UIView alloc] initWithFrame:CGRectMake(0, 20, 300, 300)];    showView.layer.borderWidth = 1.f;    showView.layer.cornerRadius = 150.f;    showView.layer.borderColor = [UIColor redColor].CGColor;    showView.center = self.view.center;    [self.view addSubview:showView];        // 新建layer    _layer = [CALayer layer];    _layer.backgroundColor = [UIColor blackColor].CGColor;        // 重置锚点    _layer.anchorPoint = CGPointMake(0.f, 0.f);        // 设置layer的frame值(在showView正中间摆放)    _layer.frame = CGRectMake(showView.middleX, showView.middleY, 150, 1);        // 添加进showView中    [showView.layer addSublayer:_layer];        // 给showView添加手势    UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];    [panGesture setMaximumNumberOfTouches:1];    [showView addGestureRecognizer:panGesture];}- (void)handlePan:(UIPanGestureRecognizer *)recognizer{    // 获取触摸点点    CGPoint translation = [recognizer locationInView:self.view];        // 计算触摸点到中心点的弧度    CGFloat angleInRadians = [Radian tanA:translation.y - self.view.center.y                                        B:translation.x - self.view.center.x];        // layer的动画    [CATransaction setDisableActions:YES];    _layer.transform = CATransform3DMakeRotation(angleInRadians, 0.0, 0.0, 1.0);}@end

以下3步非常关键:

引入POP库设计阻尼动画

效果如下:

////  RootViewController.m//  Circle////  Copyright (c) 2014年 Y.X. All rights reserved.//#import "RootViewController.h"#import "Radian.h"#import "FrameAccessor.h"#import "POP.h"@interface RootViewController ()@property (nonatomic, strong) CALayer *layer;@end@implementation RootViewController- (void)viewDidLoad{    [super viewDidLoad];    // 显示参考用的view    UIView *showView = [[UIView alloc] initWithFrame:CGRectMake(0, 20, 300, 300)];    showView.layer.borderWidth = 1.f;    showView.layer.cornerRadius = 150.f;    showView.layer.borderColor = [UIColor redColor].CGColor;    showView.center = self.view.center;    [self.view addSubview:showView];        // 新建layer    _layer = [CALayer layer];    _layer.backgroundColor = [UIColor blackColor].CGColor;        // 重置锚点    _layer.anchorPoint = CGPointMake(0.f, 0.f);        // 设置layer的frame值(在showView正中间摆放)    _layer.frame = CGRectMake(showView.middleX, showView.middleY, 150, 1);        // 添加进showView中    [showView.layer addSublayer:_layer];        // 给showView添加手势    UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];    [panGesture setMaximumNumberOfTouches:1];    [showView addGestureRecognizer:panGesture];}- (void)handlePan:(UIPanGestureRecognizer *)recognizer{    // 获取触摸点点    CGPoint translation = [recognizer locationInView:self.view];    // 将度数转换为弧度#define   RADIAN(degrees)  ((M_PI * (degrees))/ 180.f)        // 将弧度转换为度数#define   DEGREES(radian)  ((radian) * 180.f / M_PI)        if(recognizer.state == UIGestureRecognizerStateChanged)    {        // 计算触摸点到中心点的弧度        CGFloat angleInRadians = [Radian tanA:translation.y - self.view.center.y                                            B:translation.x - self.view.center.x];                POPBasicAnimation *positionAnimation = \        [POPBasicAnimation animationWithPropertyNamed:kPOPLayerRotation];        // 设置速度动画        positionAnimation.toValue = @(angleInRadians);        positionAnimation.duration = 0.01f;                // 添加动画        [_layer pop_removeAnimationForKey:@"kPOPLayerRotation"];        [_layer pop_addAnimation:positionAnimation                          forKey:@"kPOPLayerRotation"];    }        // 拖拽动作结束    if(recognizer.state == UIGestureRecognizerStateEnded)    {        // 计算触摸点到中心点的弧度        CGFloat angleInRadians = [Radian tanA:translation.y - self.view.center.y                                            B:translation.x - self.view.center.x];                // 计算出移动的速度        CGPoint velocity = [recognizer velocityInView:self.view];        CGFloat x = velocity.x;        CGFloat y = velocity.y;                // 衰退减速动画        POPDecayAnimation *positionAnimation = \        [POPDecayAnimation animationWithPropertyNamed:kPOPLayerRotation];        positionAnimation.velocity = @(+(x*ABS(cosf(angleInRadians)/100.f) +                                         y*ABS(sinf(angleInRadians)/100.f)));                // 添加动画        [_layer pop_removeAnimationForKey:@"kPOPLayerRotation"];        [_layer pop_addAnimation:positionAnimation                          forKey:@"layerPositionAnimation"];    }}@end

重点地方:

其实,实现这个效果真心挺难的......

转载地址:http://yhvol.baihongyu.com/

你可能感兴趣的文章
Css布局系列——圣杯布局
查看>>
BaseAdapter教程(1) 最简单地使用BaseAdapter
查看>>
python包管理
查看>>
【377】only one element in a tuple
查看>>
【046】◀▶ HTML 关键字
查看>>
css---媒体查询
查看>>
浅谈Js原型的理解
查看>>
Spark技术内幕: Task向Executor提交的源码解析
查看>>
git for c#,文件改动内容
查看>>
linux syslog 日志采集系统搭建
查看>>
xuyaojiade
查看>>
大神的博客地址
查看>>
50道Java线程面试题汇总
查看>>
阿里云
查看>>
maven可用镜像
查看>>
hihocoder 1582 : Territorial Dispute (计算几何)(2017 北京网络赛E)
查看>>
图片加载方式
查看>>
Linux c readdir是非线程安全,需用readdir_r,要注意用静态变量当做返回值的函数的非线程安全性...
查看>>
关于Class.forName(className).newInstance()介绍
查看>>
CentOS nginx安装淘宝开源模块nginx_concat_module时的问题记录
查看>>