iOS学习笔记-069.手势识别03——抽屉控件实现
来源:互联网 发布:java onvif 编辑:程序博客网 时间:2024/06/14 01:00
- 手势识别03抽屉控件实现
- 一预览
- 二简单分析
- 三创建基本布局
- 四添加手势
- 五界面拖拽时的处理
- 1 左边和中间控件滑动分析
- 2 右边和中间控件滑动分析
- 3 三个控件的滑动的分析
- 六敲击手势处理
- 七代码示例
手势识别03—抽屉控件实现
一、预览
实现一个左右可以滑动的抽屉控件效果,如下图:
二、简单分析
实现上面的这个控件效果
1.能够拖动,说明我们可以使用,拖拽手势
2.界面有三个部分组成,左边的控件、中间的控件、右边的控件
3.这个三个界面中,我们拖拽都在中间这个控件上,所有我们可以给中间的控件添加拖拽手势
4.添加界面会发现,中间的控件会占满界面,说明需要给控制器的view添加一个敲击手势
通过以上的分析,我们可以发现,这个抽屉控件,主要有5个部分组成:
- 左边的控件(UIView)
- 中间的控件(UIView)
- 右边的控件(UIView)
- 中间控件的拖拽手势(UIPanGestureRecognizer)
- 控制器view的敲击手势(UITapGestureRecognizer)
ok~~~
三、创建基本布局
基本布局由左中右三个控件组成
-(void)createLayout{ //创建leftView UIView * leftV = [[UIView alloc]initWithFrame:self.view.bounds]; leftV.backgroundColor = [UIColor blueColor]; [self.view addSubview:leftV]; self.leftView = leftV; //创建rightView UIView * rightV = [[UIView alloc]initWithFrame:self.view.bounds]; rightV.backgroundColor = [UIColor redColor]; [self.view addSubview:rightV]; self.rightView = rightV; //创建mainView UIView * mainV = [[UIView alloc]initWithFrame:self.view.bounds]; mainV.backgroundColor = [UIColor greenColor]; [self.view addSubview:mainV]; self.mainView = mainV;}
四、添加手势
布局创建好了以后,我们添加手势,主要添加两个手势:
- 中间控件的拖拽手势(UIPanGestureRecognizer)
- 控制器view的敲击手势(UITapGestureRecognizer)
-(void)addGesture{ //给mainView添加拖动手势 UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panGesture:)]; [self.mainView addGestureRecognizer:pan]; //给控制器的view添加点击手势,一点击,就回到主界面上来 UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapGesture)]; [self.view addGestureRecognizer:tap];}
五、界面拖拽时的处理
5.1 左边和中间控件滑动分析
滑动的时候,如上面的图显示,图1为正常状态,此时中间的view占满屏幕,我们滑动进行分析,分析的终止点是 拖拽手势结束
向右滑动的分析
- 图1–>图2–>图1 : 从正常状态向右滑动,最终停留在 图2 这种状态(中间view的x(图3中的x)没有超过屏幕宽度的一半),这种情况,我们需要让它自动变为正在状态,即 图1
- 图1–>图3–>图4 : 从正常状态向右滑动,最终停留在 图3这种状态(中间view的x(图3中的x)超过了屏幕宽度的一半),这种情况,我们需要让它自动变为右边状态,即 图4
- 图4向右–>图4 :右边状态向右滑动,我们恢复到 右边状态 图4
通过上面的分析,我们得出结论:
向右滑动结束,我们只需要判断,中间控件的 x 是否超过屏幕的一半,超过了图4状态,没超过图1状态
向左滑动的分析
1. 图4–>图3–>图4
2. 图4–>图2–>图1
向左滑动,我们的判断依据还是中间view的x值(距离左边的值)。
综合上述: 左、中控件的滑动,我们只需要判断 x值(中间控件距离左边的距离)大于屏幕的一边,大于图4,小于图1
5.2 右边和中间控件滑动分析
向左滑动的分析
- 图5–>图6–>图5
- 图5–>图7–>图8
- 图8向左–>图8
向左滑动的时候:我们可以通过 中间view的最大x值(图6中的maxX)是否超过屏幕的一半来判断,没超过图8状态,超过图5状态
向右滑动的分析
- 图8–>图7–>图8
- 图8–>图6–>图5
向左滑动时候得出的结论同上。
综合上述:右、中控件滑动的时候,我们只需要判断maxX值(图6中的maxX)是否超过屏幕的一半来判断,没超过图8状态,超过图5状态
5.3 三个控件的滑动的分析
通过上面的分析,我们可以做如下的判断(拖拽结束时):
- 判断x值,是否超过屏幕的一半,超过了图4状态,没超过走第2步骤
- 判断maxX值,是否超过屏幕的一半,没超过图8状态,超过走第3步骤
- 恢复原来的状态
#define targetR 275#define targetL -275-(void)panGesture:(UIPanGestureRecognizer*)pan{ //获取到偏移量量 CGPoint panP =[pan translationInView:self.mainView]; //为什么不使用transform,是因为我们还要去修改高度,使用transform,只能修改,x,y //self.mainV.transform = CGAffineTransformTranslate(self.mainV.transform, transP.x, 0); self.mainView.frame = [self frameWithOffsetX:panP.x]; //判断拖动方向 if (self.mainView.frame.origin.x>0) {//右 self.rightView.hidden = YES; } else if(self.mainView.frame.origin.x<0){//左 self.rightView.hidden = NO; } //自动点位计算 //拖动结束以后做判断 //1.x值大于一半的屏幕宽度,说明在右侧 //2.maxX值小于一半的屏幕宽度,说明在左侧 CGFloat target = 0; if(pan.state == UIGestureRecognizerStateEnded){ if(self.mainView.frame.origin.x > 0.5*screenW){//右侧 target = targetR; }else if(CGRectGetMaxX(self.mainView.frame) < 0.5*screenW){ //获取最大的x值,判断,当前是小于屏幕的一半 target = targetL; } //计算view的frame CGFloat offSet = target - self.mainView.frame.origin.x; [UIView animateWithDuration:0.1 animations:^{ self.mainView.frame = [self frameWithOffsetX:offSet]; }]; } [pan setTranslation:CGPointZero inView:self.mainView];}#define maxY 100//根据偏移量计算MainV的frame- (CGRect)frameWithOffsetX:(CGFloat)offsetX { CGRect frame = self.mainView.frame; //x值的计算 frame.origin.x += offsetX; //y值得计算 //最大值是 maxY ,就是拖动的view的x值等于屏幕的宽度的时候就是这个值 //拖动最小的时候,就是0 //所以可以知道 y 的变化为: y = x * maxY/screenW CGFloat y = fabs( frame.origin.x * maxY / screenW ); frame.origin.y = y; //计算高度,其实高度就是 屏幕的高度减去两倍计算的y值 frame.size.height = [UIScreen mainScreen].bounds.size.height - 2*frame.origin.y; return frame;}
六、敲击手势处理
点击屏幕,我们恢复到正常状态图1
-(void)tapGesture{ //mainView复位 [UIView animateWithDuration:0.1 animations:^{ self.mainView.frame = self.view.bounds; }];}
七、代码示例
//// DragViewController.m// 03_UIView62_抽屉效果//// Created by 杞文明 on 17/4/2.// Copyright © 2017年 杞文明. All rights reserved.//#import "DragViewController.h"#define screenW [UIScreen mainScreen].bounds.size.width@interface DragViewController ()@property(weak,nonatomic)UIView* leftView;@property(weak,nonatomic)UIView* rightView;@property(weak,nonatomic)UIView* mainView;@end@implementation DragViewController- (void)viewDidLoad { [super viewDidLoad]; //创建布局 [self createLayout]; //添加手势 [self addGesture];}-(void)createLayout{ //创建leftView UIView * leftV = [[UIView alloc]initWithFrame:self.view.bounds]; leftV.backgroundColor = [UIColor blueColor]; [self.view addSubview:leftV]; self.leftView = leftV; //创建rightView UIView * rightV = [[UIView alloc]initWithFrame:self.view.bounds]; rightV.backgroundColor = [UIColor redColor]; [self.view addSubview:rightV]; self.rightView = rightV; //创建mainView UIView * mainV = [[UIView alloc]initWithFrame:self.view.bounds]; mainV.backgroundColor = [UIColor greenColor]; [self.view addSubview:mainV]; self.mainView = mainV;}-(void)addGesture{ //给mainView添加拖动手势 UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panGesture:)]; [self.mainView addGestureRecognizer:pan]; //给控制器的view添加点击手势,一点击,就回到主界面上来 UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapGesture)]; [self.view addGestureRecognizer:tap];}-(void)tapGesture{ //mainView复位 [UIView animateWithDuration:0.1 animations:^{ self.mainView.frame = self.view.bounds; }];}#define targetR 275#define targetL -275-(void)panGesture:(UIPanGestureRecognizer*)pan{ //获取到偏移量量 CGPoint panP =[pan translationInView:self.mainView]; //为什么不使用transform,是因为我们还要去修改高度,使用transform,只能修改,x,y //self.mainV.transform = CGAffineTransformTranslate(self.mainV.transform, transP.x, 0); self.mainView.frame = [self frameWithOffsetX:panP.x]; //判断拖动方向 if (self.mainView.frame.origin.x>0) {//右 self.rightView.hidden = YES; } else if(self.mainView.frame.origin.x<0){//左 self.rightView.hidden = NO; } //自动点位计算 //拖动结束以后做判断 //1.x值大于一半的屏幕宽度,说明在右侧 //2.maxX值小于一半的屏幕宽度,说明在左侧 CGFloat target = 0; if(pan.state == UIGestureRecognizerStateEnded){ if(self.mainView.frame.origin.x > 0.5*screenW){//右侧 target = targetR; }else if(CGRectGetMaxX(self.mainView.frame) < 0.5*screenW){ //获取最大的x值,判断,当前是小于屏幕的一半 target = targetL; } //计算view的frame CGFloat offSet = target - self.mainView.frame.origin.x; [UIView animateWithDuration:0.1 animations:^{ self.mainView.frame = [self frameWithOffsetX:offSet]; }]; } [pan setTranslation:CGPointZero inView:self.mainView];}#define maxY 100//根据偏移量计算MainV的frame- (CGRect)frameWithOffsetX:(CGFloat)offsetX { CGRect frame = self.mainView.frame; //x值的计算 frame.origin.x += offsetX; //y值得计算 //最大值是 maxY ,就是拖动的view的x值等于屏幕的宽度的时候就是这个值 //拖动最小的时候,就是0 //所以可以知道 y 的变化为: y = x * maxY/screenW CGFloat y = fabs( frame.origin.x * maxY / screenW ); frame.origin.y = y; //计算高度,其实高度就是 屏幕的高度减去两倍计算的y值 frame.size.height = [UIScreen mainScreen].bounds.size.height - 2*frame.origin.y; return frame;}@end
- iOS学习笔记-069.手势识别03——抽屉控件实现
- iOS学习笔记-070.手势识别04——抽屉控件使用
- iOS 学习笔记 手势识别
- iOS学习笔记-068.手势识别02——捏合、拖拽、旋转手势
- IOS学习笔记(14)手势识别
- ios学习笔记之手势识别
- iOS学习笔记06-手势识别
- iOS实现手势识别
- OpenCV学习笔记(二十)——手势识别
- iOS 自定义控件——抽屉功能
- ios自用学习笔记-触摸事件与手势识别
- iOS 手势识别——敲击 Tap
- iOS 手势识别——拖拽
- iOS 手势识别——UIGestureRecognizer
- ios手势学习笔记
- iOS手势学习笔记
- iOS开发——抽屉效果实现
- 使用GestureOverlayView控件实现手势识别
- springmvc整合freemarker以及前端的一些坑
- python标准库之fnmatch,dis,timeit
- [C++]union联合体总结
- K-means 之国足小例子
- 剑指offer第二题
- iOS学习笔记-069.手势识别03——抽屉控件实现
- web安全与防御---3.kali环境下sqlmap的注入
- Promotions Gym
- MSSql dbcc checkdb 出现错误处理
- 快速上手Ubuntu之安装常用软件篇——打造一个满足基本娱乐办公的Ubuntu
- iOS scene之间的跳转类型——Segue
- 运维小技巧:使用ss命令代替 netstat,和netstat说再见
- C/C++使用Select检索MySQL中的数据
- 分布式事务中2PC与3PC的区别