ios 关于UIView 的multipleTouchEnabled 和 exclusiveTouch
做项目时发现,在一个界面上的2个button竟然可以同时点击,依次push进去了2个 controller!我就产生了疑问,一个view的multipleTouchEnabled属性默认是false啊,那怎么会可以同时点击这个view上的2个子view呢?原来是对multipleTouchEnabled属性理解不对!下面看看对这个属性的理解。
multipleTouchEnabled的官方解释如下:
When set to true, the receiver receives all touches associated with a multi-touch sequence. When set to false, the receiver receives only the first touch event in a multi-touch sequence. The default value of this property is false. Other views in the same window can still receive touch events when this property is false. If you want this view to handle multi-touch events exclusively, set the values of both this property and the exclusiveTouch property to true.
exclusiveTouch的官方解释如下:
Setting this property to true causes the receiver to block the delivery of touch events to other views in the same window. The default value of this property is false.
注意:touch events的发送,是以window为一个组,而不是某个在window下的子view。 看到这里其实就可以得出结论了,如果你不想让2个button同时点击,只需要把它们的exclusiveTouch都设定为YES,就行了!multipleTouchEnabled没这个作用,我用错了属性!
参考的官方文档 Event Handling Guide,这个文档需要仔细阅读!
一个父view的multipleTouchEnabled属性不会影响它的子view的multipleTouchEnabled属性,也就是说,在一个multipleTouchEnabled = false的父view里,仍然可以有接受多个手指点击消息的子view。
再来看这个函数touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent),这里有2个参数,官方说明如下:
The set object. The passed-in NSSet contains all touches that are new or have changed in the phase represented by the method, such as UITouchPhaseBegan for the touchesBegan:withEvent: method.
The event object. The passed-in UIEvent object contains all of the touches for a given multitouch sequence.
The multipleTouchEnabled property is set to NO by default, which means that a view receives only the first touch in a multitouch sequence. When this property is disabled, you can retrieve a touch object by calling the anyObject method on the set object because there is only one object in the set.
下面是另一部分解释
The set of touches is a set (NSSet) of UITouch objects, representing new or changed touches for that phase. For example, when a touch transitions from the Began phase to the Moved phase, the app calls the touchesMoved:withEvent: method. The set of touches passed in to the touchesMoved:withEvent: method will now include this touch and all other touches in the Moved phase. The other parameter is an event (UIEvent object) that includes all touch objects for the event. This differs from the set of touches because some of the touch objects in the event may not have changed since the previous event message.
这里提到了一个名词 a multitouch sequence,一个sequence指从第一个手指按下到最后一个手指抬起,也可以通过以下的话理解:
iOS recognizes touches as part of a multitouch sequence. During a multitouch sequence, the app sends a series of event messages to the target responder.
上面的意思就是ios把所有的touch事件都作为 a multitouch sequence 的一部分,在a multitouch sequence生命周期内,不断发送touch event到target。
Each of these touch methods correspond to a touch phase: Began, Moved, Ended, and Canceled. When there are new or changed touches for a given phase, the app object calls one of these methods. Each method takes two parameters: a set of touches and an event.
所谓的multipleTouchEnabled = false 指的是这个view 只接收一个multitouch sequence中的第一个点在自己上面的手指的event信息,其余的手指event变化信息,都不会被这个view理会,所以对于一个multipleTouchEnabled = false的view来说,touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) ,第一个参数中永远只有一个touch对象,就是那个手指的event信息,而后边的event则会包含整个multitouch sequence 中的点击信息。
因此,可以看出multipleTouchEnabled这个属性不是为了控制这个view下的整个 tree 的点击控制的。这就导致了即使在一个multipleTouchEnabled=false的view上,放置了多个button,可以用多个手指同时点击这些button!
我们看一个例子,代码如下
class TouchView: UIView {
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
var touchSet = event.allTouches()
println("touchesBegan...touches set count is \(touches.count)")
println("UIEvent touch count is \(touchSet!.count)")
} }
class ViewController: UIViewController {
@IBOutlet weak var view1: UIView!
@IBOutlet weak var view2: UIView!
override func viewDidLoad() {
super.viewDidLoad()
self.view.multipleTouchEnabled = false
view1.multipleTouchEnabled = true
view2.multipleTouchEnabled = false
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
println("self view touchesBegan.....")
}
}
界面截图如下
黄色是self.view 蓝色和红色是2个touchview,我们的点击方式如下
1.点击蓝色view,不放开
2.点击蓝色view,不放开
3.点击红色view,不放开
4.点击红色view,不放开
5.点击蓝色view,不放开
控制台输出如下:
touchesBegan...touches set count is
UIEvent touch count is
touchesBegan...touches set count is
UIEvent touch count is
touchesBegan...touches set count is 1
UIEvent touch count is 3
touchesBegan...touches set count is
UIEvent touch count is
这里的第三条是红色view第一次点击的输出,第二次的红色view点击输出没有,因为它的view2.multipleTouchEnabled = false
再来另一个测试:
1.点击黄色,不放开
2.点击蓝色,不放
3.点击红色,不放
输出如下:
self view touchesBegan.....
touchesBegan...touches set count is
UIEvent touch count is
touchesBegan...touches set count is
UIEvent touch count is
另外说一点,如果这里我们没有对红色和蓝色的类重写 touchesBegan 方法,那么系统默认会把消息交给 self.view 也就是黄色view处理。
ios 关于UIView 的multipleTouchEnabled 和 exclusiveTouch的更多相关文章
- 荼菜的iOS笔记--UIView的几个Block动画
前言:我的第一篇文章荼菜的iOS笔记–Core Animation 核心动画算是比较详细讲了核心动画的用法,但是如你上篇看到的,有时我们只是想实现一些很小的动画,这时再用coreAnimation就会 ...
- iOS学习——UIView的研究
在iOS开发中,我们知道有一个共同的基类——NSObject,但是对于界面视图而言,UIView是非常重要的一个类,UIView是很多视图控件的基类,因此,对于UIView的学习闲的非常有必要.在iO ...
- iOS开发UIView.h简介
1.UICoordinateSpace不同坐标空间的坐标切换 @protocol UICoordinateSpace <NSObject> //将当前的坐标空间点转换到指定的坐标空间 - ...
- iOS 使用UIView的一种有效方法
在一个典型的MVC结构 中,Model部分负责保存目标数据,View部分主要负责实现数据的界面以及将数据显示出来,二者在Controller的操作下协同工作.在iOS应用中,View的实现主要由UIV ...
- IOS自定义UIView
IOS中一般会用到几种方式自定义UIView 1.继承之UIView的存代码的自定义View 2.使用xib和代码一起使用的自定义View 3.存xib的自定义View(不需要业务处理的那种) 本文主 ...
- OpenGL ES: iOS 自定义 UIView 响应屏幕旋转
iOS下使用OpenGL 如果使用GLKit View 那么不用担心屏幕旋转的问题,说明如下: If you change the size, scale factor, or drawable pr ...
- iOS:UIView的CALayer基本演练
UIView的CALayer基本演练的属性和注意事项: 在UIView中创建一个按钮UIButton,然后设置UIButton的Layer属性 –圆角.边框.阴影及3D形变属性 注意: 1.在UIVi ...
- IOS设置UIView的边框为圆角
iOS 系统自带的 View 组件都是正方形的,看起来都太生硬,有时候我需要变成圆角形式,如下图: 具体的实现是使用QuartzCore库,下面我具体的描述一下实现过程: • 首先 ...
- iOS 中 UIView 和 CALayer 的关系
UIView 有一个名叫 layer ,类型为 CALayer 的对象属性,它们的行为很相似,主要区别在于:CALayer 继承自 NSObject ,不能够响应事件. 这是因为 UIView 除了负 ...
随机推荐
- PhpStorm 快捷键
不容易记住的: Ctrl + Shift + F 查找文本,在项目目录或指定的目录 Ctrl + Shift + R 查找文本并替换,在项目目录或指定的目录 Ctrl + E 打开最近关闭的 ...
- org.apache.commons.lang.StringUtils中常用的方法
org.apache.commons.lang.StringUtils中常用的方法,这里主要列举String中没有,且比较有用的方法: 1. 检查字符串是否为空: static boolean isB ...
- jelq
初级 The Newbie Routine 5 minutes hot wrap 5 minutes manual stretch (ten 30-second stretches) 10 minut ...
- Exception→"Source":"EntityFramework" "Message" :"更新条目时出错。有关详细信息,请参阅内部异常。"
给一个数据库中类型为"datetime"的列赋值为 "DateTime.MinValue"...... 而// ::} But--01到9999-- :: 到 ...
- 给select添加自定义值和选项
添加选项: document.getElementById("id_select").options.add(new Option("name", " ...
- hadoop之根据Rowkey从HBase中查询数据
1.Hbase 根据rowkey 查询 conf的配置信息如下: conf = new Configuration(); conf.set("hbase.zookeeper.quorum&q ...
- Mac Pro 修改环境变量
参考:Ubuntu 12 修改环境变量 [实战] 把 php.php-fpm.nginx.mysql 的相关命令路径添加到 用户环境变量 $ vim ~/.bash_profile alias ll= ...
- Swift3.0P1 语法指南——基础
原档:https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programmi ...
- springmvc之定时器
一.通过注解方式实现定时器 1.工程结构 2.所需jar包 3.spring-config.xml,springmvc配置文件 <?xml version="1.0" enc ...
- 基于jQuery的对象切换插件:soChange 1.5 (点击下载)
http://www.jsfoot.com/jquery/demo/2011-09-20/192.html 所有参数: $(obj).soChange({ thumbObj:null, //导 ...