计算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(, , , )];
showView.layer.borderWidth = .f;
showView.layer.cornerRadius = .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(.f, .f); // 设置layer的frame值(在showView正中间摆放)
_layer.frame = CGRectMake(showView.middleX, showView.middleY, , ); // 添加进showView中
[showView.layer addSublayer:_layer]; // 给showView添加手势
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[panGesture setMaximumNumberOfTouches:];
[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(, , , )];
showView.layer.borderWidth = .f;
showView.layer.cornerRadius = .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(.f, .f); // 设置layer的frame值(在showView正中间摆放)
_layer.frame = CGRectMake(showView.middleX, showView.middleY, , ); // 添加进showView中
[showView.layer addSublayer:_layer]; // 给showView添加手势
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[panGesture setMaximumNumberOfTouches:];
[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)/.f) +
y*ABS(sinf(angleInRadians)/.f))); // 添加动画
[_layer pop_removeAnimationForKey:@"kPOPLayerRotation"];
[_layer pop_addAnimation:positionAnimation
forKey:@"layerPositionAnimation"];
}
} @end

重点地方:

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

计算Pan手势到指定点的角度的更多相关文章

  1. 限定pan手势只能在圆内移动view

    限定pan手势只能在圆内移动view 效果: 虽然看起来很简单,但实现原理还是稍微有点复杂-_-!! 核心的地方,就是需要计算pan手势的点与指定点的距离,不能超过这个距离,超过了就让动画还原,很容易 ...

  2. PHP计算二维数组指定元素的和

    array_sum(array_column($arr, 'num')); //计算二维数组指定元素的和 $arr = [ [ 'id'=>1, 'num'=>3, ], [ 'id'=& ...

  3. C#_计算目前时间到指定的周X、指定的时间X 还有多少秒

    比如:当前时间到下周二 05:00:00还剩下多少秒? /// <summary> /// 计算距离下一个 周XX XX时XX分XX秒,还剩下多少秒 /// </summary> ...

  4. [微信小程序]计算自己手机到指定位置的距离

    目的: 根据目的地的坐标计算自己手机的位置离目的地的距离的 核心思路: 后续操作必须等所有异步请求都返回了才能继续 使用 const qqmap = require("../../utils ...

  5. ios计算字符串宽高,指定字符串变色,获取URL参数集合

    #import <Foundation/Foundation.h> @interface NSString (Extension) - (CGFloat)heightWithLimitWi ...

  6. 【Python小试】计算蛋白序列中指定氨基酸所占的比例

    编码 from __future__ import division def get_aa_percentage(protein, aa_list=['A','I','L','M','F','W',' ...

  7. iOS开发 在scrollView上增加滑动手势(Pan)

    view上有一个scrollView,现在想在view上加一个Pan手势,需求是:当向下划的时候,整个view动,但是scrollView不动:其它情况下scrollView动而view不动. -(B ...

  8. ios手势

    iOS 手势操作:拖动.捏合.旋转.点按.长按.轻扫.自定义 大 中 小   1.UIGestureRecognizer 介绍 手势识别在 iOS 中非常重要,他极大地提高了移动设备的使用便捷性. i ...

  9. iOS 手势操作:拖动、捏合、旋转、点按、长按、轻扫、自定义

    1.UIGestureRecognizer 介绍 手势识别在 iOS 中非常重要,他极大地提高了移动设备的使用便捷性. iOS 系统在 3.2 以后,他提供了一些常用的手势(UIGestureReco ...

随机推荐

  1. HUE配置文件hue.ini 的Spark模块详解(图文详解)(分HA集群和HA集群)

    不多说,直接上干货! 我的集群机器情况是 bigdatamaster(192.168.80.10).bigdataslave1(192.168.80.11)和bigdataslave2(192.168 ...

  2. 《python灰帽子》学习笔记:调试器设置

    一.构造 C  数据类型 C Type | Python Type | ctypes Type ____________________________________________________ ...

  3. PTA (Advanced Level) 1012 The Best Rank

    The Best Rank To evaluate the performance of our first year CS majored students, we consider their g ...

  4. amazeui笔记-Cookie

  5. spring AOP为什么配置了没有效果?

     spring Aop的配置一定要配置在springmvc配置文件中         springMVC.xml 1 <!-- AOP 注解方式 :定义Aspect --> <!-- ...

  6. 对JDK、JRE和JVM的一些浅薄理解

    JDK:JDK(Java Development Kit),顾名思义是java程序的开发包,任何java程序想要运行都需要相应版本的JDK,可以到oracle下载(下载之后自带JRE和编译工具等,无需 ...

  7. Groovy中String转换Gstring用于动态插值

    知识点是Groovy中的模板引擎 GStringTemplateEngine 第一个例子: def binding = [ firstname : "Grace", lastnam ...

  8. hdu 1054 Strategic Game 经典树形DP

    Strategic Game Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  9. 高并发第二弹:并发概念及内存模型(JMM)

    高并发第二弹:并发概念及内存模型(JMM) 感谢 : 深入Java内存模型 http://www.importnew.com/10589.html, cpu缓存一致性 https://www.cnbl ...

  10. Python Django ORM创建基本类以及生成数据结构

    #在项目目录下的modules.py中创建一个类,来自动生成一张表UserInfo class UserInfo(models.Model): username = models.CharField( ...