计算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 ...
随机推荐
- ok6410 android driver(2)
I will paste and anlaysis a small character device driver in this paragraph. #include <linux/modu ...
- Install NDK in Eclipse/Android Studio
1. Download NDK https://developer.android.com/tools/sdk/ndk/index.html 2.Install NDK $ tar xvf andro ...
- Java类文件结构及javac的ClassReader类解读
首先来看一下ClassFile,类注释如下: A JVM class file. Generic Java classfiles have one additional attribute for c ...
- 【开源组件】FastDFS集群搭建与实战
FastDFS是一个轻量级的分布式文件系统,在实际生产环境往往以集群的形式部署,保证了服务的高可用.本文重点阐述FastDFS集群的搭建和项目实战. 工作流程 上传流程图 下载流程图 基本概念可参考作 ...
- JS 开发者必须知道的十个 ES6 新特性
这篇文章会给你简单介绍一下ES6.如果你还不知道什么是ES6的话,它是JavaScript一个新的实现,如果你是一个忙碌的JavaScript开发者(但谁不是呢),那么继续读下去吧,看看当今最热门的语 ...
- weblogic升级之ddconverter
1. weblogic8.x 升到weblogic10时,需要升级ejb响应的描述符,否则会报错. BEA-011114 - Error: For EJB modules, deployment pl ...
- Canvas 绘制矩形,圆形,不规则图形(线条),渐变等图像效果
绘制矩形: getContext("2d") 对象是内建的 HTML5 对象,拥有多种绘制路径.矩形.圆形.字符以及添加图像的方法. fillStyle 方法将其染成红色,fill ...
- 解决 swap file “*.swp”already exists!问题
用vim编辑文件实际上是先copy一份临时文件,病映射到内存给你编辑,编辑的是临时文件,当执行:w后才保存临时文件到原文件,执行:q后才删除临时文件. 每次启动检索是否有临时文件,有就询问如何处理, ...
- 应输入 #endregion 指令报错的排查技巧
VS2010中错误排查的一个小技巧,欢迎大家吐槽: 错误 9 应输入 #endregion 指令sses.cs 3778 2 xxx.xx 这个错很明显,是缺少#endr ...
- ie6的设置外边距margin变双倍的问题
子元素避免同时使用float和margin. 如: 需要子元素的margin-bottom:20px时,可以给用父元素设置padding-bottom:20px代替.