iOS手势 总结归纳
来源:互联网 发布:中国证券市场数据库 编辑:程序博客网 时间:2024/05/18 01:04
最近需要把项目中的播放器中的手势层重构,顺便总结了iOS的手势相关的代码。
1.单击双击共存的代码
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap)];//双击
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTap)];
[doubleTap setNumberOfTapsRequired:2];
[self.view addGestureRecognizer:singleTap];
[self.view addGestureRecognizer:doubleTap];
[singleTap requireGestureRecognizerToFail:doubleTap];
2.滑动相关手势
UISwipeGestureRecognizer * swipeGes = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(recog)];
[swipeGes setDirection:UISwipeGestureRecognizerDirectionUp];
[self.view addGestureRecognizer:swipeGes];
UISwipeGestureRecognizer通常用作滑动,优点是代码简单,系统自动判断滑动方向。缺点是不能持续触发,有时不方便使用。
通常,有时也用UIPanGestureRecognizer实现滑动手势,好处是能随着手指在屏幕上移动而持续触发滑动的相关事件,在事件中持续获得滑动的相应参数,可以实现连续控制。由于比较复杂,放在最后的demo 中
3.其他手势
其他手势不在一一总结,简述如下:
UIPinchGestureRecognizer(捏合)
UIRotationGestureRecognizer(旋转)
UILongPressGestureRecognizer(长按)
长按很简单,捏合和旋转暂时没有用过,最后补充一段简单的代码。
PS1:
以下代码是一段视频播放器中手势代码。主要实现了单击显示控制视图,双击暂停/播放,左侧上下滑动调节亮度,右侧上下滑动调节音量,左右滑动控制播放进度
ControlView中如下:
①三个全局变量的手势,其中,_pan处理所有的滑动,待会仔细介绍。另外俩分别处理单击,双击。还有三个变量是控制触发频率的全局变量,稍后介绍。
CGPoint _beginTouchPoint;
SlideDirect _direct;
NSInteger _currentDegree;
UIPanGestureRecognizer * _panGes;
UITapGestureRecognizer * _singleTapGes;
UITapGestureRecognizer * _doubleTapGes;
②初始化这三个手势并添加到视图中。单击双击比较简单,主要是滑动模块,需要自己判断滑动方向,距离大小
- (void)initGesture{
_singleTapGes = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapReceived:)];
//双击
_doubleTapGes = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapReceived:)];
[_doubleTapGes setNumberOfTapsRequired:2];
[self addGestureRecognizer:_singleTapGes];
[self addGestureRecognizer:_doubleTapGes];
[_singleTapGes requireGestureRecognizerToFail:_doubleTapGes];
_panGes = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[self addGestureRecognizer:_panGes];
_currentDegree = 1;
}
触发的时间
- (void)handlePan:(UIPanGestureRecognizer *)sender
{
switch (sender.state) {
case UIGestureRecognizerStateBegan:
{
//开始滑动,则记录下来作为起始点
_beginTouchPoint = [sender locationInView:sender.view];
break;
return;
}
case UIGestureRecognizerStateChanged:
{
//滑动持续进行中。。。
//获取当前点的坐标
CGPoint newPoint = [sender locationInView:sender.view];
if (_direct == SlideDirectNone ) {
//当前没有滑动方向,则给其赋值
CGFloat degree = fabs((newPoint.y - _beginTouchPoint.y) / (newPoint.x - _beginTouchPoint.x));
//degree表示当前点和起始点之间连线的斜率。防止误判,只有斜率过高/过低,才能判定滑动方向,进而判断是向上下左右滑动。
if (degree > 1.5f) {
_direct = newPoint.y < _beginTouchPoint.y ? SlideDirectUp : SlideDirectDown;
}
else if (degree < 0.6){
_direct = newPoint.x > _beginTouchPoint.x ? SlideDirectRight : SlideDirectLeft;
}
}
if (_direct == SlideDirectNone) {
//仍然没有方向,说明之前判断滑动方向时没有达到临界值,则不认为是正常的滑动,则此次跳出;
break;
}
//已判断出当前方向,则进行方法的调用
switch (_direct) {
case SlideDirectUp:
{
CGFloat degree = _beginTouchPoint.y - newPoint.y;
if (_beginTouchPoint.x < (kScreenWidth / 2.0)) {
//左侧,调节亮度
[self gestureSlideGes:GesTypeBrightnessUp degre:degree];
}else{
//右侧,调节音量
[self gestureSlideGes:GesTypeVoiceUp degre:degree];
}
}
break;
case SlideDirectDown:
{
CGFloat degree = newPoint.y - _beginTouchPoint.y;
if (_beginTouchPoint.x < (kScreenWidth / 2.0)) {
//左侧,调节亮度
[self gestureSlideGes:GesTypeBrightnessDown degre:degree];
}else{
//右侧,调节音量
[self gestureSlideGes:GesTypeVoiceDown degre:degree];
}
}
break;
case SlideDirectLeft:
{
//在滑动过程中触发左滑/右滑,则只触发开始滑动,
CGFloat degree = newPoint.x - _beginTouchPoint.x;
[self gestureSlideGes:GesTypeBeginSlide degre:degree];
}
break;
case SlideDirectRight:
{
CGFloat degree = newPoint.x - _beginTouchPoint.x;
[self gestureSlideGes:GesTypeBeginSlide degre:degree];
}
break;
default:
break;
}
}
break;
case UIGestureRecognizerStateEnded:
{
if (_direct == SlideDirectRight || _direct == SlideDirectLeft) {
//如果是左右滑动,抬起时需要触发特殊事件,上下滑则不关心最后的抬起
CGPoint newPoint = [sender locationInView:sender.view];
CGFloat degree = newPoint.x - _beginTouchPoint.x;
[self gestureSlideGes:_direct == SlideDirectLeft ? GesTypeBackward : GesTypeForward degre:degree];
}
_direct = SlideDirectNone;
_currentDegree = 1;
}
break;
default:
break;
}
}
- (void)gestureSlideGes:(GesType)ges degre:(CGFloat )degre{
if (fabs(degre) < _currentDegree * 30.0f && ges != GesTypeForward && ges != GesTypeBackward) {
//如果是普通上下滑动,则是调节亮度或者音量。
//因为pan手势触发太过于频繁,不可能每次都触发增加/减少亮度/音量,
//因为这两个总共就是20个档左右,太过敏感。故只有滑动距离达到30的整数倍时才能正常触发
return;
}
_currentDegree ++;
if ([self.baseDelegate respondsToSelector:@selector(recogGes:degree:)]) {
[self.baseDelegate recogGes:ges degree:degre];
}
}
补充:因为视频播放解码比较慢,不能做到随着左右滑动实时将对应的视频解码出来,只能在滑动中调节进度条,等到手指抬起时将对应进度条的视频解码出来
PS2:
手势的状态,
typedef NS_ENUM(NSInteger, UIGestureRecognizerState) {
UIGestureRecognizerStatePossible, // 尚未识别是何种手势操作(但可能已经触发了触摸事件),默认状态
UIGestureRecognizerStateBegan, // 手势已经开始,此时已经被识别,但是这个过程中可能发生变化,手势操作尚未完成
UIGestureRecognizerStateChanged, // 手势状态发生转变
UIGestureRecognizerStateEnded, // 手势识别操作完成(此时已经松开手指)
UIGestureRecognizerStateCancelled, // 手势被取消,恢复到默认状态
UIGestureRecognizerStateFailed, // 手势识别失败,恢复到默认状态
UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded // 手势识别完成,同UIGestureRecognizerStateEnded
};
- iOS手势 总结归纳
- ios-手势总结-清扫手势
- iOS手势总结
- iOS(总结)手势
- ios-手势总结demo
- iOS UIGestureRecognizer手势总结
- iOS 手势简单使用总结
- IOS手势总结与UIResponder
- iOS开发中的手势总结
- 【iOS开发-手势】iOS中各种手势总结
- iOS开发-归纳总结(上)
- iOS开发-归纳总结(下)
- iOS手势UIGestureRecognizer用法总结(摘抄部分)
- iOS 触摸和手势总结
- 总结iOS开发中的手势识别
- IOS手势使用及总结:UIPanGestureRecognizer 拖拽
- 关于iOS Swipe手势的一点总结
- iOS开发之手势识别 总结
- 实现Fragment滑动onFling的手势识别
- 循环神经网络(RNN)学习资源
- 64位机器上plsql连接64位oracle
- UE4抗锯齿选项的开启
- CentOS 6.5下编译安装新版LNMP
- iOS手势 总结归纳
- Don't forget your original intention.
- spring集成rocketmq
- I/O模型: 阻塞、非阻塞、I/O复用、同步、异步
- 告别占内存的Android studio,让编程飞起来
- hibernate的缓存机制详细解析
- if后执行多条语句的用法-简单的排序
- 分类算法评价(集合)
- Storm简介