IOS中手势UIGestureRecognizer
通常在对视图进行缩放移动等操作的时候我们可以用UIScrollView,因为它里边自带了这些功能,我们要做的就是告诉UIScrollView的几个相关参数就可以了
但是没有实现旋转的手势即UIRotationGestureRecognizer
IOS中手势有很多:
UIRotationGestureRecognizer旋转
UITapGestureRecognizer手指点击
UIPinchGestureRecognizer缩放
UISwipeGestureRecognizer手指快速扫过
UIPanGestureRecognizer手指拖拽移动
UILongPressGestureRecognizer长按
怎么去实现自己的UIScrollView呢,还可以旋转其Content呢?
需要UIRotationGestureRecognizer、UIPinchGestureRecognizer、UIPanGestureRecognizer的组合操作,先实现单个的操作
UIPanGestureRecognizer:
func panOnView(panGesture:UIPanGestureRecognizer){
println("PanClick!")
switch(panGesture.state){
case .Ended:
println("end")
case .Began:
//
println("began")
// velocity = CGPoint(x: panGesture.velocityInView(view).x * fps, y: panGesture.velocityInView(view).y * fps)//初始速度
case .Changed:
var trans = panGesture.translationInView(view)
imageCenter!.transform = CGAffineTransformTranslate(imageCenter!.transform, trans.x / currentScale, trans.y / currentScale)
panGesture.setTranslation(CGPointZero, inView: view)//translate的时候,center和position都不变
default:
println("default")
}
// adjustAnchorPointForGestureRecognizer(panGesture)
}
UIPinchGestureRecognizer:
//缩放
func pintchOnView(pintchGesture:UIPinchGestureRecognizer){ currentScale = getViewScale(pintchGesture)
switch pintchGesture.state{
case .Began:
case .Ended:
println("end")
case .Changed:
var scale = pintchGesture.scale
pintchGesture.view!.transform = CGAffineTransformScale(pintchGesture.view!.transform,scale, scale)
pintchGesture.scale = 1
default:
println("default")
} }
UIPanGestureRecognizer:
func rotateOnView(rotateGesture:UIRotationGestureRecognizer){
switch rotateGesture.state{
case .Began:
case .Ended:
println("end")
case .Changed:
imageCenter?.transform = CGAffineTransformRotate(imageCenter!.transform, rotateGesture.rotation)
rotateGesture.rotation = 0
println("changed")
default:
println("default")
}
}
组合操作:
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
一定要实现上面的函数才能组合操作,值得注意的是,因为缩放和旋转都有个中心点的问题,也是常说的瞄点,瞄点不一样,缩放和旋转产生的效果完全不一样
在视图的Layer中有一个属性anchorPoint这个点一般的默认值是(0.5,0.5)值大小是从0~1变化。如何理解瞄点,其实很简单,比如说瞄点是P点,在P处的视图上有一个很小的小花儿(假设有这个参照物),旋转之后无论图形变成什么样子,那个参照物小花儿还是在屏幕的原来的位置。比如P(0.5,0.5)那就是在视图的正中心缩放旋转,(0,0)就是左上角旋转缩放,(1,1)就是右下角缩放旋转。
如果在组合操作的时候不设置瞄点,每次手指操作的位置不同,瞄店都会变化,你不重现设置,很有可能你一旋转,视图都不知道跑哪里去了,所以在所有手势的Begin枚举的时候,应该手动再设置当前手指操作的点作为瞄点
func adjustAnchorPointForGestureRecognizer(gestureRecognizer:UIGestureRecognizer){
stopTimer()
var piece = gestureRecognizer.view
var locationInView = gestureRecognizer.locationInView(piece)
var locationInSuperview = gestureRecognizer.locationInView(piece?.superview)
piece?.layer.anchorPoint = CGPoint(x: locationInView.x / piece!.bounds.size.width, y: locationInView.y / piece!.bounds.size.height)
piece?.center = locationInSuperview
var trans = imageCenter!.transform
imageCenter!.transform = CGAffineTransformTranslate(trans, -trans.tx / currentScale, -trans.ty / currentScale)
panGestureRecognizer.setTranslation(CGPointZero, inView: view)
}
惯性:
在很多操作中我们都会看见视图缓动的动画效果,感觉好像视图在受到阻力。很多动画库里边都有这样的效果。但是动画一般都是密封的过程,也就是说假如一个移动动画持续5秒,那么在这五秒结束之前,你不能对其坐标手动赋值,除非你用一个全新的移动动画来代替它。所以常用计时器来自己写一个缓动的动画
var fps:CGFloat = 1 / 60.0//假设在每次fps时间间隔就对对象位置赋值
var factor:CGFloat = 0.95//摩擦系数
var velocity = ?//手指脱离屏幕的瞬间,视图朝某个方向运动的速度,例如移动动画的缓动,将手指抬起的坐标减去抬起之前的上一个坐标,这个距离向量作为初识的速度
定义一个计时器,时间间隔为fps,每隔fps,将velocity累乘一个factor系数。视图的坐标每次就加上velocity,直到velocity=0,终止计时器。不光移动动画可以,任意的动画都可以采用这个方法,简单的实现缓动效果,好处在于,这种动画缓动摩擦系数可以自己控制,而且可以在任意缓动的过程中对对象重新定位动画的属性,只要在之前关闭计时器即可
IOS中手势UIGestureRecognizer的更多相关文章
- [BS-25] IOS中手势UIGestureRecognizer概述
IOS中手势UIGestureRecognizer概述 一.概述 iPhone中处理触摸屏的操作,在3.2之前是主要使用的是由UIResponder而来的如下4种方式: - (void)touches ...
- 点击事件touches与ios的手势UIGestureRecognizer
.h文件 @property (weak,nonatomic) IBOutlet UILabel *messageLabel;@property (weak,nonatomic) IBOutlet U ...
- 关于iOS的手势UIGestureRecognizer问题
typedef NS_ENUM(NSInteger, UIGestureRecognizerState) { UIGestureRecognizerStatePossible, // 尚未识别是何种手 ...
- ios 中手势用法
pan拖动手势 - (void)viewDidLoad { [super viewDidLoad]; [self Pan]; // Do any additional setup after load ...
- IOS各种手势操作实例
先看下效果 手势相关的介绍 IOS中手势操作一般是 UIGestureRecognizer 类的几个手势子类去实现,一般我们用到的手势就这么5种: 1.点击 UITapGestureRecogniz ...
- iOS中的触摸事件和手势处理
iOS中的事件可以分为三大类: 1> 触摸事件 2> 加速计事件 3> 远程控制事件 响应者对象 在iOS中不是任何对象都能处理事件,只有继承了UIResponder的对象才能接收并 ...
- 说说iOS中的手势及触摸
一.响应链 在IOS开发中会遇到各种操作事件,通过程序可以对这些事件做出响应. 首先,当发生事件响应时,必须知道由谁来响应事件.在IOS中,由响应者链来对事件进行响应,所有事件响应的类都是UIResp ...
- iOS手势UIGestureRecognizer的使用及手势冲突的解决办法【转】
转自:iOS开发中的手势体系——UIGestureRecognizer分析及其子类的使用 关于手势的一篇很好的帖子,转载过来免得丢失.你可能最感兴趣的是手势间的互斥处理,那么就搜索 4.手势间的互斥处 ...
- iOS手势UIGestureRecognizer的使用失效问题
问题:视图正常展示在界面中,父层是放在window上的,底部的一个控件的点击事件失效(所有设置都正常) 解决思路:虽然视图能够正常展示,但是发现父类视图的底部尺寸比子类的视图的尺寸小,也就是说上层视图 ...
随机推荐
- Spring Boot:Caused by: org.apache.ibatis.binding.BindingException: Parameter 'deptId' not found.
1. 错误信息描述 在使用Spring Boot + Mybaits从前台向后台提交数据时,控制台报出该错误信息 2. 报错原因 在dao接口中,该方法拥有两个参数,Mybaits无法区分这两个参数 ...
- Arduino 101/Genuino101使用-第2篇
1. Arduino 101编程只是在ARC的核心上进行,其具体架构为ARCv2EM.. 2. 而Quark核心,从目前可知的信息来看,其应该运行着名为Zephyr的RTOS 3.101并没有EEPR ...
- Maven学习(五)-----如何从Maven远程存储库下载?
如何从Maven远程存储库下载? 根据 Apache Maven 的说明: Downloading in Maven is triggered by a project declaring a dep ...
- 用php实现简单的自制计算器
存档: <!DOCTYPE html> <html> <head> <title>PHP实现计算器</title> </head> ...
- Windows网络通信(二):socket异步编程
简述 这里使用的API和同步编程的API是差不多的,只多了一个ioctlsocket和select函数.这里面涉及一个很重要的结构体fd_set.这里用到的API大部分都是windows和linux通 ...
- asp.net 问题:Web 服务器上的请求筛选模块被配置为 拒绝包含的查询字符串过长的请求
发现问题: post请求,在发送一个图片base64编码的字符串时,服务端报这个错误. 报错信息中给出了解决办法: 最可能的原因: Web 服务器上的请求筛选被配置为拒绝该请求,因为查询字符串过长. ...
- MySQL事务、并发问题、锁机制
MySQL事务,并发问题,锁机制 1.什么是事务 事务是一条或多条数据库操作语句的组合,具备ACID,4个特点. 原子性:要不全部成功,要不全部撤销 隔离性:事务之间相互独立,互不干扰 一致性:数据库 ...
- 基于C#的机器学习--模糊逻辑-穿越障碍
模糊逻辑-穿越障碍 模糊逻辑.另一个我们经常听到的术语.但它的真正含义是什么?它是否意味着不止一件事?我们马上就会知道答案. 我们将使用模糊逻辑来帮助引导一辆自动驾驶汽车绕过障碍,如果我们做得正确,我 ...
- Alpha阶段第2周/共2周 Scrum立会报告+燃尽图 02
此次作业要求参见 [https://edu.cnblogs.com/campus/nenu/2018fall/homework/2285] Scrum master:祁玉 一.小组介绍 组长:王一可 ...
- MySQL数据库错误号:2003 - Can't connect to MYSQL server on 'localhost'(10061)
打开Windows+R在里面输入services.msc打开服务 在MySQL服务是右键点击启动,让其状态显为正在运行即可 启动完毕,然后再用命令CMD去连接,或者Navicat都不再报上面的错