计算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. 利用IDEA创建Web Service服务端和客户端的详细过程

    创建服务端 一.file–>new–>project 二.点击next后输入服务端名,点击finish,生成目录如下 三.在 HelloWorld.Java 文件中右击,选 WebServ ...

  2. 001-Servlet模板

    package ${enclosing_package}; import java.io.IOException; import javax.servlet.ServletException; imp ...

  3. Difference between $.ajax() and $.get() and $.load()

    转自:Difference between $.ajax() and $.get() and $.load() $.ajax() is the most configurable one, where ...

  4. 使用 Python 编写脚本并发布

    使用 Python 编写脚本并发布 P1: 脚本 通常在 Linux 服务器上会遇到在命令行中输入命令的操作,而有些操作包含的命令数目较多或者其中的命令包含的参数较多,如果一个一个的敲命令的话就太麻烦 ...

  5. android系统权限的管理

    被权限搞了好久,决定好好的研究一下: 参考资料 http://blog.csdn.net/xieyan0811/article/details/6083019?reload http://blog.c ...

  6. 从零开始学JAVA(07)-使用SpringMVC4写helloworld

    一.关于开发环境 Eclipse IDE for Java EE Developers Jdk 1.7 (32位版本) SpringMVC 4.1.5.RELEASE apache-tomcat-7. ...

  7. CSS3动画积累+动画库+3d动画

    一.animates.css animate.css是来自dropbox的工程师Daniel Eden开发的一款CSS3的动画效果小类库.包含了60多款不同类型的CSS3动画,包括:晃动,闪动,各种淡 ...

  8. 关于PHP数据库mysql的一些案例

    案例1:查询select 使用php连接数据库class9, 获取数据库的表student中的信息, 然后输出到页面上(用表格套住) <?php header("Content-typ ...

  9. 【C#】RGB转CMYK

    由于目前印兔项目中的在线设计功能设计出来的产品颜色模式不确定,但是客户设计出来的产品需要发送到印厂的客户端去下载并且印刷,只有CMYK颜色模式的产品才能正确印刷,所以需要判断产品的颜色模式是否为CMY ...

  10. Vue学习笔记:methods、computed、watch的区别

    自:https://www.jb51.net/article/120073.htm 首先要说,methods,watch和computed都是以函数为基础的,但各自却都不同 而从作用机制和性质上看,m ...