计算Pan手势到指定点的角度
计算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手势到指定点的角度的更多相关文章
- 限定pan手势只能在圆内移动view
限定pan手势只能在圆内移动view 效果: 虽然看起来很简单,但实现原理还是稍微有点复杂-_-!! 核心的地方,就是需要计算pan手势的点与指定点的距离,不能超过这个距离,超过了就让动画还原,很容易 ...
- PHP计算二维数组指定元素的和
array_sum(array_column($arr, 'num')); //计算二维数组指定元素的和 $arr = [ [ 'id'=>1, 'num'=>3, ], [ 'id'=& ...
- C#_计算目前时间到指定的周X、指定的时间X 还有多少秒
比如:当前时间到下周二 05:00:00还剩下多少秒? /// <summary> /// 计算距离下一个 周XX XX时XX分XX秒,还剩下多少秒 /// </summary> ...
- [微信小程序]计算自己手机到指定位置的距离
目的: 根据目的地的坐标计算自己手机的位置离目的地的距离的 核心思路: 后续操作必须等所有异步请求都返回了才能继续 使用 const qqmap = require("../../utils ...
- ios计算字符串宽高,指定字符串变色,获取URL参数集合
#import <Foundation/Foundation.h> @interface NSString (Extension) - (CGFloat)heightWithLimitWi ...
- 【Python小试】计算蛋白序列中指定氨基酸所占的比例
编码 from __future__ import division def get_aa_percentage(protein, aa_list=['A','I','L','M','F','W',' ...
- iOS开发 在scrollView上增加滑动手势(Pan)
view上有一个scrollView,现在想在view上加一个Pan手势,需求是:当向下划的时候,整个view动,但是scrollView不动:其它情况下scrollView动而view不动. -(B ...
- ios手势
iOS 手势操作:拖动.捏合.旋转.点按.长按.轻扫.自定义 大 中 小 1.UIGestureRecognizer 介绍 手势识别在 iOS 中非常重要,他极大地提高了移动设备的使用便捷性. i ...
- iOS 手势操作:拖动、捏合、旋转、点按、长按、轻扫、自定义
1.UIGestureRecognizer 介绍 手势识别在 iOS 中非常重要,他极大地提高了移动设备的使用便捷性. iOS 系统在 3.2 以后,他提供了一些常用的手势(UIGestureReco ...
随机推荐
- 对于maven创建spark项目的pom.xml配置文件(图文详解)
不多说,直接上干货! http://mvnrepository.com/ 这里,怎么创建,见 Spark编程环境搭建(基于Intellij IDEA的Ultimate版本)(包含Java和Scala版 ...
- Git学习系列之Git基本操作克隆项目(图文详解)
不多说,直接上干货! 想必,能进来看我写的这篇博文的朋友,肯定是了解过. 比如SVN的操作吧,最常见的是 检出(Check out ...), 更新 (Update ...), 以及 提交(Commi ...
- [转]WxEmojiView
本文转自:https://github.com/icindy/WxEmojiView 来源信息 author: Di (微信小程序开发工程师) organization: WeAppDev(微信小程序 ...
- jquery里判断数组内是否包含了指定的值或元素的方法
本文讲的是在jquery里,如何判断一个数组里是否包含了指定的值,变量,或其它对象元素的方法. 在jquery里,我们可以用$.inArray来判断一个数组里是否包含了指定的值或其它对象元素,来看一个 ...
- Spring 学习(五)--- 事务(未完成)
问题 : Spring 事务传播机制是怎么样的,在什么应用场景使用 事务是什么 我们使用的框架可能是Hibernate/JPA或者是Mybatis,都知道的底层是需要一个session/connect ...
- thinkphp htmlspecialchars_decode
一 百度编辑器 与 htmlspecialchars_decode *Thinkphp百度编辑器 存的时候为了安全把进行了字符转换,数据库: <p> 测试测试</ ...
- 记DateTime.Now.ToString()遇到的一个坑
最近在编写一个程序中遇到的 程序的简要逻辑就是一个timer控件 1.获取当前时间的短时间,例如 13:15 2.使用获取到的短时间去一个列表中查询是否有匹配的,列表中是一串短时间,类似 {" ...
- 六:SpringCloud-Config
十:SpringCloudConfig分布式配置中心 1. 概述 1.1 分布式系统面临的 配置问题 微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的 ...
- sql: MySQL and Microsoft SQL Server Stored Procedures IN, OUT using csharp code
MySQL存储过程: #插入一条返回值涂聚文注 DELIMITER $$ DROP PROCEDURE IF EXISTS `geovindu`.`proc_Insert_BookKindOut` $ ...
- HDU P2222 Keywords Search
In the modern time, Search engine came into the life of everybody like Google, Baidu, etc.Wiskey als ...