Swift UIGestureRecognizer介绍
来源:互联网 发布:mac优酷客户端 编辑:程序博客网 时间:2024/05/02 04:46
- UIGestureRecognizer
- UIGestureRecognizer是一个抽象类,定义了所有手势的基本行为,使用它的子类才能等到具体手势
- UITapGestureRecognizer 敲击
- UIPinchGestureRecognizer 捏合,用于缩放
- UIPanGestureRecognizer 拖拽
- UISwipeGestureRecognizer 轻扫
- UIRotationGestureRecognizer 旋转
- UILongPressGestureRecognizer 长按
- UIScreenEdgePanGestureRecognizer 屏幕边缘平移 手势
- 常用属性和方法
- UIGestureRecognizer是一个抽象类,定义了所有手势的基本行为,使用它的子类才能等到具体手势
public init(target: Any?, action: Selector?) // 为手势添加动作 (一个手势可以拥有多个动作,当手势相应时会一同触发其所有的事件) open func addTarget(_ target: Any, action: Selector) // 移除动作 open func removeTarget(_ target: Any?, action: Selector?)// 设置手势可用 open var isEnabled: Bool// 获取手势所作用的 view open var view: UIView? { get }// 获取手势在指定 view 的坐标 open func location(in view: UIView?) -> CGPoint// 获取触发手势的触摸数 open var numberOfTouches: Int { get }
- 除了以上的几个属性外还有一些属性也十分重要
// 默认为 true,当为 true 的时候,当适当的视图和手势接收器接收到了触摸之后会发送touchesCancelled给适当的视图,以取消视图对该触摸的响应,该触摸也就不会继续在事件传递链传递下去。设置为 false 则不会终止事件的传递 open var cancelsTouchesInView: Bool// 默认为 false ,当为false 的时候,手势接收器会先捕捉到该触摸,然后发送给适当的视图,两者适当做出相应 当设置为 true 的时候,手势识别器在识别的过程中,不会将触摸传递给视图,只有当识别失败之后才会传递给适当的视图,此时延时大概0.15ms open var delaysTouchesBegan: Bool// 默认是 true 这种情况下发生一个touch时,在手势识别成功后,发送给touchesCancelled消息给适当的视图,手势识别失败时,会延迟大概0.15ms,期间没有接收到别的touch才会发送touchesEnded。如果设置为NO,则不会延迟,即会立即发送touchesEnded以结束当前触摸。 open var delaysTouchesEnded: Bool// 参考资料 http://blog.csdn.net/fys_0801/article/details/50605837
- 手势状态
public enum UIGestureRecognizerState : Int { case possible // 默认的状态,这个时候的手势并没有具体的情形状态 case began // 手势开始被识别的状态 case changed // 手势识别发生改变的状态 case ended // 手势识别结束,将会执行触发的方法 case cancelled // 手势识别取消 case failed // 识别失败,方法将不会被调用 public static var recognized: UIGestureRecognizerState { get } }
- 代理方法
// 手指触摸屏幕后回调的方法,返回NO则不再进行手势识别,方法触发等 optional public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool// 是否接受手势 true 为接受 optional public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool// 是否支持多手势触发,返回YES,则可以多个手势一起触发方法,返回NO则为互斥 optional public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool// 下面这个两个方法也是用来控制手势的互斥执行的// 这个方法返回YES,第一个手势和第二个互斥时,第一个会失效 optional public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool// 这个方法返回YES,第一个和第二个互斥时,第二个会失效 optional public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool// ios9之后推出,目前作用不明,请大佬指导一下 optional public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive press: UIPress) -> Bool
- UIPanGestureRecognizer 拖拽手势
- 在创建一个需要跟随手指滑动而滑动的视图的时候在手势的action 中注意如下几点
- 获取 pan 手势相对于 pan.state == .begin 的位置
- 在创建一个需要跟随手指滑动而滑动的视图的时候在手势的action 中注意如下几点
let panGesOffset = pan.translate(in:view)
- 设置要被滑动的视图的位移
self.center.x += position.x self.center.y += position.y//or self.transform = self.transform.translatedBy(x:position.x , y: position.y)//注意如果需要用到视图经过 transform 之后的 width 的话,就需要用 frame.width 而不能用 bounds.width 并且经过 transform 之后的的 center 是始终不变的
- 将 panGes 的 translate 置零
// 由于 translate 是相对于 state==.begin 的位置,所以在每次的 pan 动作结束之后都需要为 translate 置零 panGes.setTranslation(CGPoint.zero, in: self)
- UITapGestureRecognizer 敲击
- 创建
let tapGes = UITapGestureRecognizer(target: self, action: #selector(tapGesAction(_:))) tapGes.delegate = self tapGes.addTarget(self, action: #selector(anohterGesAction)) view.addGestureRecognizer(tapGes)// 方法@objc func tapGesAction(_ tapGes : UITapGestureRecognizer){ print("tapGesLocation\(tapGes.location(in: view))") }
- UIPinchGestureRecognizer 捏合,用于缩放
- 注意点
// ges.scale 是相对于最初大小的缩放倍数
- 示例 : 缩放视图
// 创建缩放手势 let pinchGes = UIPinchGestureRecognizer(target: self, action: #selector(pinchGesAction(_ :))) pinchTestView.addGestureRecognizer(pinchGes)// 方法 @objc func pinchGesAction(_ ges : UIPinchGestureRecognizer){ print(#function) // 实现缩放 // 获取到的 scale 都是默认相对于最开始的大小 let scale = ges.scale pinchTestView.transform = pinchTestView.transform.scaledBy(x: scale, y: scale) // 复位 ges.scale = 1 }
- UISwipeGestureRecognizer 轻扫
- 注意点
// 读取轻扫手势是有一个默认的方向的 : 从左向右,默认情况下只能读取这个手势// 改变读取的手势方向 swip.direction// 一个轻扫手势只能设定一个轻扫方向,如果一个控件需要监听多个方向的事件,这个时候就需要添加多个手势。
- 示例 : 轻扫移动视图
// 创建轻扫手势 let swipeGes = UISwipeGestureRecognizer(target: self, action: #selector(swipeGesAction(_:))) // 设置轻扫方向 swipeGes.direction = .down swipeTestView.addGestureRecognizer(swipeGes)// 方法@objc func swipeGesAction(_ ges : UISwipeGestureRecognizer){ swipeTestView.transform = swipeTestView.transform.translatedBy(x: 10, y: 0) }
- UIRotationGestureRecognizer 旋转
- 注意点
// ges.rotation 获取到的旋转角度是以触发动作的初始位置来计算的,所以旋转视图完毕之后要置零
- 示例 : 旋转视图
// 创建缩放手势 let rotationGes = UIRotationGestureRecognizer(target: self, action: #selector(rotationGesAction(_:))) self.swipeTestView.addGestureRecognizer(rotationGes)// 方法@objc func rotationGesAction(_ ges : UIRotationGestureRecognizer){ let rotation = ges.rotation swipeTestView.transform = swipeTestView.transform.rotated(by: rotation) // 置零 ges.rotation = 0 }
- UILongPressGestureRecognizer 长按
- 注意点
// 由于在长按的时候可能长按手势会被触发多次,所以在其触发事件中需要判断手势的一个状态// longPress.state
- 示例 : 长按显示 UIMenuController
// 创建长按手势 let longPressGes = UILongPressGestureRecognizer(target: self, action: #selector(labelLongPressAction(_:))) // 长按手势最小触发时间 longPressGes.minimumPressDuration = 1 // 需要点击的次数 // longPressGes.numberOfTapsRequired = 1 // 长按手势需要的同时敲击触碰数(手指数) longPressGes.numberOfTouchesRequired = 1 // 长按有效移动范围(从点击开始,长按移动的允许范围 单位 px longPressGes.allowableMovement = 15 label.isUserInteractionEnabled = true label.addGestureRecognizer(longPressGes)// 方法 关于 UIMenuController 具体请看上一篇博客// http://blog.csdn.net/eiamor/article/details/78235796@objc func labelLongPressAction( _ sender : UILongPressGestureRecognizer){ // 如果 Menu 已经被创建那就不再重复创建 menu if (UIMenuController.shared.isMenuVisible){ return } // 注意:长安手势可以触发两次事件,我们需要判断手势状态,如下// if (sender.state == .ended) { // 要成为第一响应者否则某些功能会错乱,例如 label 未成为第一响应者但是 label 的 menu 有 paste 功能会直接 paste 到第一响应者上// label.becomeFirstResponder() // 由于系统只允许一个 UIMenuController 存在,所以创建 UIMenuController 是以单例的形式获取的 let menu = UIMenuController.shared // 设置 Menu 所显示的 items menu.menuItems = [UIMenuItem(title: "item1", action: #selector(objAction)), UIMenuItem(title: "item2", action: #selector(objAction)), UIMenuItem(title: "item3", action: #selector(objAction)), UIMenuItem(title: "item4", action: #selector(objAction))] // 设置箭头方向 menu.arrowDirection = .default // 设置添加上 menu 的目标控件的 rect 和目标控件 menu.setTargetRect(label.bounds, in: label) // 令 Menu 可见 menu.setMenuVisible(true, animated: true)// } }
- UIScreenEdgePanGestureRecognizer 屏幕边缘平移 手势
- 注意点
//1. 视图位置(屏幕边缘) //2. 设置edges属性 // 设置屏幕边缘手势支持方法 // 需要添加到控制器的根视图上才能生效
- 示例
// 创建边缘平移手势 let edgeGes = UIScreenEdgePanGestureRecognizer(target: self, action: #selector(edgeGesAction(_:))) edgeGes.edges = .left view.addGestureRecognizer(edgeGes)// 方法@objc func edgeGesAction(_ ges : UIScreenEdgePanGestureRecognizer){ swipeTestView.transform = swipeTestView.transform.translatedBy(x: 0, y: 20) }
参考资料 :
https://my.oschina.net/u/2340880/blog/527077
http://www.cocoachina.com/ios/20130501/6108.html
http://www.jianshu.com/p/5aca8a413d40
http://www.jianshu.com/p/4ac617c9493b
http://blog.csdn.net/fys_0801/article/details/50605837
阅读全文
0 0
- Swift UIGestureRecognizer介绍
- UIGestureRecognizer介绍
- UIGestureRecognizer介绍
- UIGestureRecognizer 介绍
- swift教程-使用UIGestureRecognizer
- 1、UIGestureRecognizer介绍
- UIGestureRecognizer的简单介绍
- UIGestureRecognizer手势 : 1-概要介绍
- UIGestureRecognizer
- UIGestureRecognizer
- UIGestureRecognizer
- UIGestureRecognizer
- UIGestureRecognizer
- UIGestureRecognizer
- UIGestureRecognizer
- UIGestureRecognizer
- UIGestureRecognizer
- UIGestureRecognizer
- Google分享会
- Nginx expires缓存
- ssh整合时遇到Error creating bean with name 'sessionFactory' defined in class
- [RK3288][Android6.0] 调试笔记 --- hwclock命令无法使用
- plsql12 格式化sql 语句
- Swift UIGestureRecognizer介绍
- MYCAT使用篇(1)
- C# 实现AOP 的几种常见方式
- React Native 网络请求封装:使用Promise封装fetch请求
- 抓老鼠啊~亏了还是赚了?
- 【题目】[USACO5.2]蜗牛的旅行Snail Trails
- ICMP洪水
- LDAP启动:slaptest: bad configuration file!
- postgis最短路径查询