关于UIView用户交互相关的属性和方法
UIView除了负责展示内容给用户外还负责响应用户事件
1、交互相关的属性
userInteractionEnabled 默认是YES ,如果设置为NO则不响应用户事件,并且把当前控件从事件队列中删除。也就是说设置了userInterfaceEnabled属性的视图会打断响应者链导致该view的subview都无法响应事件。
multipleTouchEnabled 默认是NO,如果设置为YES则支持多点触碰。
exclusiveTouch 默认是NO,如果设置为YES则当前UIView会独占整个Touch事件。具体来说就是如果UIView设置了exclusiveTouch属性为YES则当这个UIView成为第一响应者时,在手指离开屏幕前其他view不会响应任何touch事件。
作用举例:UITableView的每个cell都需要使用exclusive,否则同时点击多个cell会触发每个视图的事件响应。手势识别会忽略此属性。
2、触摸响应
了解UIView的触碰响应之前,首先了解在iOS中触碰事件是什么,事件在视图模型中是如何传递的,视图在接收到一个事件是如何响应的。下面介绍触碰事件类UITouch和响应者链来解释事件的工作原理。
在iOS中UITouch类代表触碰事件。当用户触摸屏幕后就会产生相应的事件,所有相关的UITouch对象都被包装在事件中,被程序交由特定的对象处理。UITouch对象包括触碰的详细信息。
UITouch含有5个属性:
window:触碰产生时所处的窗口,由于窗口可能发生变化,当前所在的窗口不一定是最开始的窗口。
view:触碰产生时所处的视图。由于视图可能发生变化,当前视图也不一定是最初的视图。
tapCount:短时间内轻击(tap)屏幕的次数,可根据tapCount判断单击、双击或更多的轻击。
timestamp:时间戳记录了触碰事件产生或变化时的时间。单位是秒。
phase:触碰事件在屏幕上有一个周期,即触碰开始、触碰点移动、触碰结束,中途取消。通过phase可以查看当前触碰事件在一个周期中所处的状态。UITouchPhase枚举:
UITouchPhaseBegan
UITouchPhaseMoved
UITouchPhaseStationary
UITouchPhaseEnded
UITouchPhaseCancelled
当手指触碰到屏幕,无论是单点还是多点触碰,事件都会开始,直到用户所有的手指都离开屏幕。期间所有的UITouch对象都被封装在UIEvent事件对象中,由程序分发给处理者。事件记录了这个周期中所有触碰对象状态的变化。
只要屏幕被触摸,系统会将诺干个触碰信息封装到UIEvent对象中发送给程序,由管理程序UIApplication对象将事件分发。
响应者对象就是可以响应事件并对事件作出处理的对象。在iOS中UIResponder类定义了响应者对象的所有方法。UIApplication、UIWindow、UIViewController、UIView以及UIKit中继承自UIView的控件都间接或直接继承自UIResponder类,这些类都可以当做响应者。
响应者链表示一系列响应者对象组成的事件传递的链条。当确定了第一响应者后,事件交由第一响应者处理,如果第一响应者不处理事件沿着响应者链传递,交给下一个响应者。一般来说,第一响应者是UIView对象或者UIView的子类对象,当其被触摸后事件交由它处理,如果它不处理,事件就会交给它的UIViewController处理(如果存在),然后是它的superview父视图对象,以此类推,直到顶层视图。如果顶层视图不处理则交给UIWindow对象处理,再到UIApplication对象(如果UIApplication继承自UIResponder)。如果整个响应者链都不响应这个事件则该事件被丢弃。
UIView类继承了UIResponder类,要对事件作出处理还需要重写UIResponder类中定义的事件处理函数。根据不同的触碰状态,程序会调用相应的处理函数,这些函数包括:
-(void) touchesBegan:(NSSet *)touches withEvents:(UIEvent *)event;
-(void) touchesMoved:(NSSet *)touches withEvents:(UIEvent *)event;
-(void) touchesEnded:(NSSet *)touches withEvents:(UIEvent *)event;
-(void) touchesCancelled:(NSSet *)touches withEvents:(UIEvent *)event;
这几个方法被调用时,对应了UITouch类中的phase属性的4个枚举值。当触碰被取消,如触碰过程中被来电打断,会调用touchesCancelled:touches:方法。
这些方法在开发中并不需要全部实现,可以根据需要重写特定的方法。这4个方法都有两个相同的参数:NSSet类型的touches和UIEvent类型的event。Touches表示触碰产生的所有的UITouch对象,event表示事件。因为UIEvent包含了整个触碰过程中所有的触碰对象,所以可以调用allTouches 方法获取该事件内所有触碰对象,也可以调用touchesForView;或者touchesForWindows;取出特定视图或者窗口上的触碰对象。在这几个事件中,都可以拿到触碰对象,然后根据其位置、状态、时间属性做逻辑处理。
轻击操作很容易引起歧义,比如用户点击了一次之后,并不知道用户是想单击还是只是双击的一部分,或者点了两次之后并不知道用户是想双击还是继续点击。可以使用延迟调用函数解决这个问题。
-( void )touchesEnded:( NSSet *)toucheswithEvent:(UIEvent { UITouch if (touch.tapCount== { [ self performSelector: @selector (setBackground:) withObject:[UIColor } else if (touch.tapCount== { [ self cancelPreviousPerformRequestsWIthTarget: self selector: @selector (setBackground:) object:[UIColor self .view.backgroundColor= } } |
除了触碰事件外UIResponder还提供了运动事件的支持。
运动事件的方法:
-(void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event 摇动事件开始
-(void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event 摇动事件结束
-(void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event 摇动事件被中断
远程事件:
-(void)remoteControlReceivedWithEvent: 音乐后台播放控制的时候会用到
第一响应者的相关函数:
- (BOOL)canBecomeFirstResponder 默认返回NO
- (BOOL)becomeFirstResponder
- (BOOL)canResignFirstResponder 默认返回YES
- (BOOL)resignFirstResponder;
- (BOOL)isFirstResponder
可以通过becomeFirstResponder方法注册成为第一响应者,通过resignFirstResponder方法不成为第一响应者。比如通过这两个方法操作UITextField来控制键盘的现隐藏。
3、手势
属性:
NSArray *gestureRecognizers
可以通过这个属性获取当前UIView的所有手势对象。手势在触碰事件处理流程中,处于观察者的角色,其不是view层级结构的一部分,所以不参与响应者链。在将触摸事件发送给hit-testview之前,系统会先将触碰事件发送到view绑定的Gesture
Recognizer上。
UIView关于手势的方法:
-(void) addGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer 增加一个手势。
-(void) removeGestureRecognizer:(UIGestureRecognizer *)getureRecognizer 删除一个手势。
-(BOOL) gestureRecognizerShouldBegan:(UIGestureRecognizer *)gestureRecognizer 询问是否开始执行该手势,默认返回YES。
手势相比触碰事件的好处是可以直接使用已经定义好的手势,开发者不用自己计算手指移动轨迹。手势识别的基类是UIGestureRecognizer,是一个抽象类,定义了实现底层手势识别行为的编程接口。衍生类如下:
UITabGestureRecognizer 轻击手势,如:首先创建一个UIView,然后创建响应者,把响应者添加到UIView上,执行响应者对应的方法即可实现点击功能。
UIPinchGestureRecognizer 捏合手势
UIRotationGestureRecognizer 旋转手势
UISwipeGestureRecognizer 轻扫手势
UIPanGestureRecognizer 拖拽手势
UILongPressGestrueRecognizer 长按手势
UIGestureRecognizer主要方法:
-(id) initWithTarget:action: 初始化方法
-(void)addTarget:action:
-(void)removeTarget:action:
主要属性:
UIGestureRecognizerState state 手势识别当前状态
有以下几种情况:
UIGestureRecognizerStatePossibel, 未识别状态
UIGestureRecognizerStateBegan, 手势开始
UIGestureRecognizerStateChanged, 手势改变
UIGestureRecognizerStateEnded,手势结束
UIGestureRecognizerStateFailured 手势失败,被其他事件中断。当把手势state设为这个值得时候相当于取消了这个手势。
cancelsTouchesInView 为YES时,表示当GestureRecognizers识别到手势后,会向hit-test view发送touchesCancelled:消息以取消hit-testview对触碰序列的处理,这样只有GestureRecognizer响应此次触碰,响应者链的view不再响应。如果为NO,则不发送touchesCancelled:消息,这样GestureRecognizer和view同时响应触碰事件。默认值是YES。
delaysTouchesBegan 为NO时表示触碰序列已经开始而手势识别还未识别出此手势时,touch事件会同时发给hit-testview。如果为YES,则手势在识别过程中,不会有任何触碰事件发送给hit-testview;如果手势识别器最终识别了手势,则也不会发送任何消息给hit-testview;如果手势识别器最终没有识别到手势,才会发送所有触碰事件给view处理。默认值是NO。
delaysTouchesBegan 为YES时,延迟发送touchesEnded:消息,手势失败时才发送。默认值是YES。
UITabGestureRecognizer 轻击手势任意手指任意次数的点击
属性:
numberOfTapsRequired 点击次数
numberOfTouchesRequired 手指个数
UIPinchGestureRecognizer 捏合或者扩张手势
属性:
scale:初始值为1,两手指距离减少则scale不断变小;两个手指重合则变为0;
velocity:初始值为0,手指移动的相对速度,两手指距离减少为负数,速度越快数值越少;两手指距离变大为整数,速度越快数值越大。
UIRotationGestureRecognizer 旋转手势
属性:
rotation:初始值为0,两手指的旋转弧度,顺时针旋转为正数,逆时针旋转为负数。
velocity:初始值为0手指一动的相对速度,顺时针为正数越快值越大;逆时针为负越快越小。
UISwipGestureRecognizer 轻扫手势,一个手势只能指定一个方向,如果需要指定多个方向需要多个手势
属性:
numberOfTouchesRequired: 手指个数
direction:手势方向,如UISwipeGestureRecognizerDirectionRight向右
UIPanGestureRecognizer: 拖拽手势,相比轻扫手势,手指与屏幕的交互时间更长。
属性:
mininumNumberOfTouches 默认值为1,最少手指数量
maxnumNumberOfTouches 最大手指数量
方法:
- (CGPoint)velocityInView:(UIView*)view 返回拖拽手势的速度,值是每秒移过的point值,被分成水平和垂直两个分量。
UILongPressGestrueRecognizer: 长按手势。
属性:
numberOfTapsRequired:默认值为0,轻击的次数。
numberOfTouchesRequired:默认值是1,手指数量。
mininumPressDuration:默认值为0.5,单位是秒。
allowableMovement:默认值为10,单位是像素pixels。
多手势兼容
可以为View添加多个手势,缺省情况下,没有对手势的执行顺序排序,每次调用顺序可能都不同。通过以下方法可以控制手势的响应顺序。
-(void)requireGestureRecognizerToFail:(UIGestureRecognizer*)otherGestureRecognizer
在作为参数的GestureRecognizer失败以后手势才发生,否则手势从不会发生。
[self.panRecognizerrequireGestureRecognizerToFail:self.swipeRecognizer]; 捏合手势失败后才会触发拖拽手势。如果捏合手势成功则拖拽手势永远不会被触发
-(BOOL)canBePreventedByGestureRecognizer:(UIGestureRecognizer*)preventingGestureRecognizer
这个方法可以重载,比如UIGestureRecognizer的子类重载了这个方法返回NO,也就是说无论任何情况下子类的手势都不能被阻止,是非常强势的手势。
如果返回YES,那么preventingGestureRecognizer传入的手势就会组织子类手势。比如:
[rotationGestureRecognizercanBePreventedByGestureRecognizer:pinchGestureRecognizer]; 如果rotation手势重载了canBePreventedByGestureRecognizer方法并且返回YES。则旋转手势被捏合手势阻止,但是旋转手势不能阻止捏合手势。
还可以在方法体中加入逻辑判断。
-(BOOL)canPreventGestureRecognizer:(UIGestureRecognizer*)preventedGestureRecognizer
这个方法同样可以重载,如果返回NO则这个手势不能阻止其他任何手势。
如果返回YES,就可以阻止preventedGestureRecognizer的手势。比如:
[rotationGestureRecognizercanPreventGestureRecognizer:pinchGestureRecognizer]; 如果rotation手势重载了canBePreventedByGestureRecognizer方法并且返回YES。则旋转手势阻止了捏合手势。
UIGestureRecognizerDelegate
-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer*)gestureRecognizer
此方法在gesturerecognizer视图传出UIGestureRecognizerStatePossible状态时调用,如果返回NO,则转换成UIGestureRecognizerStateFailed;如果返回YES,则继续识别。默认返回YES
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizershouldReceiveTouch:(UITouch *)touch
此方法在window对象有触碰事件发生时,touchesBegan:withEvent:方法之前调用。如果返回NO,则GestureRecognizer忽略此触碰事件。默认返回YES。可以用于禁止某个区域的手势。
关于UIView用户交互相关的属性和方法的更多相关文章
- iOS UIView控件的常用属性和方法的总结
一 UIVIew 常见属性1.frame 位置和尺寸(以父控件的左上角为原点(0,0))2.center 中点 (以父控件的左上角为原点(0,0))3.bounds 位置和尺寸(以自己的左上角为原点 ...
- Array相关的属性和方法
这里只是做了相关的列举,具体的使用方法,请参考网址. Array 对象属性 constructor 返回对创建此对象的数组函数的引用. var test=new Array(); if (test.c ...
- 常用的Array相关的属性和方法
Array 对象属性constructor 返回对创建此对象的数组函数的引用. length 设置或返回数组中元素的数目. prototype 使您有能力向对象添加属性和方法. Array 对象方法c ...
- JavaScript 中 Object ,Prototype 相关的属性和方法
span { font-family: 'Consolas'; font-size: 10pt; color: #ffffff; } .sc0 { } .sc2 { color: #c0c0c0; } ...
- UIView用户事件响应
UIView除了负责展示内容给用户外还负责响应用户事件.本章主要介绍UIView用户交互相关的属性和方法. 1.交互相关的属性 userInteractionEnabled 默认是YES ,如果设置为 ...
- iOS学习笔记(2)— UIView用户事件响应
UIView除了负责展示内容给用户外还负责响应用户事件.本章主要介绍UIView用户交互相关的属性和方法. 1.交互相关的属性 userInteractionEnabled 默认是YES ,如果设置为 ...
- Android SDK上手指南 3:用户交互
在这篇教程中,我们将对之前所添加的Button元素进行设置以实现对用户点击的检测与响应.为了达成这一目标,我们需要在应用程序的主Activity类中略微涉及Java编程内容.如果大家在Java开发方面 ...
- Day1:用户交互与格式化输出
一.用户交互 1.input()方法 #!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Hiuhung Wan username = inpu ...
- SVG DOM常用属性和方法介绍
将以Adobe SVG Viewer提供的属性和方法为准,因为不同解析器对JavaScript以及相关的属性和方法支持的程度不同,有些方法和属性是某个解析器所特有的.SVG支持DOM2标准. 12.2 ...
随机推荐
- Spark技术内幕: Shuffle详解(一)
通过上面一系列文章,我们知道在集群启动时,在Standalone模式下,Worker会向Master注册,使得Master可以感知进而管理整个集群:Master通过借助ZK,可以简单的实现HA:而应用 ...
- 深入理解CoordinatorLayout.Behavior
要研究的几个问题 一.Behavior是什么?为什么要用Behavior? 二.怎么使用Behavior? 三.从源码角度看为什么要这么使用Behavior? 一.Behavior是什么?为什么要用B ...
- Cocos2D在Xcode7和iOS 9.2上IMP调用出错
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 原来的代码一直在Xcode6.4上和iOS 8.4上运行,没有 ...
- 谈谈spring的缓存
缓存到底扮演了什么角色 请移步: http://hacpai.com/article/1376986299174 在对项目进行优化的时候,我们可以主要从以下三个方面入手: 1 缓存 2 集群 3 异 ...
- 04 SimpleAdapter
<span style="font-size:18px;">package com.fmyboke; import java.util.ArrayList; impor ...
- Android的自动完成文本框-android学习之旅(二十六)
AutoComplicatedTextView简介 AutoComplicatedTextView是从EditText派生出来的,可以使用EditText的所有的属性.当用户输入一定的内容后,会有提示 ...
- C++对C的函数拓展 - 默认参数
1 C++中可以在函数声明时为参数提供一个默认值, 当函数调用时没有指定这个参数的值,编译器会自动用默认值代替 void myPrint(int x = 3) { printf("x:%d& ...
- ADO.NET常用方法释义
先列个列表,下面的就是常用的数据库操作的方法. ExecuteNonQuery 释义:对链接执行的SQL语句,并返回受影响的行数(注意:用它来执行目录操作,如查询数据库的结构,创建表等数据库对象,或通 ...
- 海量数据挖掘MMDS week5: 计算广告Computational Advertising
http://blog.csdn.net/pipisorry/article/details/49428053 海量数据挖掘Mining Massive Datasets(MMDs) -Jure Le ...
- C语言实现的猜数字小游戏(主要是对于自定义函数的运用)
#include <stdio.h> #include <stdlib.h> #include<time.h>//加上此头文件的作用是什么?另外不加的话有什么影响? ...