计算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. javascript004引用类型

    –掌握数组的概念.特性.常用方法(重点) –掌握Object,学会使用对象(重中之重) –了解其他引用类型对象 一:数组 •在ECMAScript中数组是非常常用的引用类型了.ECMAScript所定 ...

  2. Git提交项目到GitHub

    一.GitHub新建项目 1.进入Github首页,点击New repository新建一个项目 2.填写相应信息后点击create即可 Repository name: 仓库名称 Descripti ...

  3. [C语言]日期间天数差值的计算

    刷一些算法题时总能遇到计算日期间天数的问题,每每遇到这种情况,不是打开excel就是用系统自带的计算器.私以为这种问题及其简单以至于不需要自己动脑子,只要会调用工具就好.直到近些天在写一个日历程序的时 ...

  4. jmap查看内存使用情况与生成heapdump--转

    http://www.webspherechina.net/home/space.php?uid=191&do=blog&id=7572 如果想分析自己的JAVA Applicatio ...

  5. URL重写html后Html文件打不开解决办法

    1.首先照旧在网站配置的应用程序扩展名映射中添加扩展名.html映射到aspnet_isapi.dll,是否存在不选: 2.在web.config文件中<compilation>节点下添加 ...

  6. ef——存储过程

      数据库中存在存储过程GetCategory: ALTER proc [dbo].[GetCategory] @cid int as begin select * from Categories w ...

  7. this说明

    这个This就表示当前实例的对象,用this可访问属性,this.Fist:

  8. DataGridView 绑定数据方法

    DataGridView控件用于显示来自多种外部数据源中的数据,用户可以在此控件添加行和列,并可以填充数据.   如要让DataGridView显示数据库中的数据,只需要将此控件绑定到挑用数据库的数据 ...

  9. jQuery事件篇---基础事件

    写在前面: 有一段时间未更新博客了,利用这段时间,重新看了<jQuery基础教程 第四版>和<锋利的jQuery 第二版>,这两本书绝对是jQuery入门非常好的书,值得多读几 ...

  10. 撩课-Java每天5道面试题第14天

    101.请解释下 ORM? 对象关系映射(Object Relational Mapping)模式 是一种为了解决面向对象与关系数据库 存在的互不匹配的现象的技术. 简单来说, ORM是通过使用描述对 ...