简单的抽屉效果

简单的抽屉效果是由3 个View 组成,顶层默认显示的mainV,左边的leftV以及右边的rightV ,当mainV 监听到滑动时,计算滑动的偏移量,控制显示leftV或者rightV.

废话不多说,上代码.

一:所以,首先我们需要在头文件中定义三个View的属性,来给外界调用,实现设置对应的属性和效果:

1 @property (nonatomic, weak, readonly) UIView *mainV;
2
3 @property (nonatomic, weak, readonly) UIView *leftV;
4
5 @property (nonatomic, weak, readonly) UIView *rightV;

二:然后在实现文件中定义对应的宏,后面要用到:

 1 // @"frame"
 2 //自动提示宏
 3 #define XMGkeyPath(objc, keyPath) @(((void)objc.keyPath, #keyPath))
 4
 5 // 在宏里面如果在参数前添加了#,就会把参数变成C语言字符串
 6
 7 // 获取屏幕的宽度
 8 #define screenW [UIScreen mainScreen].bounds.size.width
 9
10 // 获取屏幕的高度
11 #define screenH [UIScreen mainScreen].bounds.size.height

宏入门:宏定义的黑魔法 - 宏菜鸟起飞手册

三:在ViewDidLoad中调用下面这个方法实现三个View的创建:

 1 // 添加所有的子控件
 2 - (void)setUpAllChildView
 3 {
 4     // left
 5     UIView *leftV = [[UIView alloc] initWithFrame:self.view.bounds];
 6     leftV.backgroundColor = [UIColor greenColor];
 7     [self.view addSubview:leftV];
 8     _leftV = leftV;
 9
10     // right
11     UIView *rightV = [[UIView alloc] initWithFrame:self.view.bounds];
12     rightV.backgroundColor = [UIColor blueColor];
13     [self.view addSubview:rightV];
14     _rightV = rightV;
15
16     // main
17     UIView *mainV = [[UIView alloc] initWithFrame:self.view.bounds];
18     mainV.backgroundColor = [UIColor redColor];
19     [self.view addSubview:mainV];
20     _mainV = mainV;
21 }

四:在ViewDidLoad中为mainV界面添加滑动手势:

 1     // 添加拖拽手势
 2     UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
 3
 4     [_mainV addGestureRecognizer:pan];
 5 

使用KVO监听frame的变化:

1
2     // KVO作用:时刻监听某个对象的某个属性的改变
3     // _main frame属性的改变
4     // Observer:观察者
5     // KeyPath:监听的属性
6     // NSKeyValueObservingOptionNew:表示监听新值的改变
7     [_mainV addObserver:self forKeyPath:XMGkeyPath(_mainV, frame) options:NSKeyValueObservingOptionNew context:nil];
8     

五:实现滑动手势的方法,和监听属性变化的方法:

 1 #define targetR 300
 2
 3 #define targetL -200
 4
 5 - (void)pan:(UIPanGestureRecognizer *)pan
 6 {
 7     // 获取手势的偏移量
 8     CGPoint transP = [pan translationInView:_mainV];
 9     // 获取x轴的偏移量,相对于上一次
10     CGFloat offsetX = transP.x;
11     // 修改最新的main.frame,
12     _mainV.frame = [self frameWithOffsetX:offsetX];
13     // 复位
14     [pan setTranslation:CGPointZero inView:_mainV];
15     // 判断下当前手指有没有抬起,表示手势结束
16     if (pan.state == UIGestureRecognizerStateEnded) { // 手指抬起,定位
17         // x>屏幕的一半,定位到右边某个位置
18         CGFloat target = 0;
19         if (_mainV.frame.origin.x > screenW * 0.5) {
20             target = targetR;
21         }else if (CGRectGetMaxX(_mainV.frame) < screenW * 0.5){
22             // 最大的x < 屏幕一半的时候,定义到左边某个位置
23             target = targetL;
24         }
25         // 获取x轴的偏移量
26         CGFloat offsetX = target - _mainV.frame.origin.x;
27         [UIView animateWithDuration:0.25 animations:^{
28             _mainV.frame = [self frameWithOffsetX:offsetX];
29         }];
30     }
31 }
32
33 #define XMGMaxY 100
34
35 // 给定一个x轴的偏移量计算下最新main的frame
36 - (CGRect)frameWithOffsetX:(CGFloat)offsetX
37 {
38
39
41
42     // 获取当前main的frame
43     CGRect frame = _mainV.frame;
44
45     // 计算当前的x,y,w,h
46     // 获取最新的x
47     CGFloat x = frame.origin.x + offsetX;
48
49     // 获取最新的y
50     CGFloat y = x / screenW * XMGMaxY;
51
52     // 当用户往左边移动的时候,_main.x < 0,y需要增加,为正
53     if (frame.origin.x < 0) {
54         y = -y;
55     }
56     // 获取最新的h
57     CGFloat h = screenH - 2 * y;
58     // 获取缩放比例
59     CGFloat scale = h / screenH;
60     // 获取最新的w
61     CGFloat w = screenW * scale;
62     return CGRectMake(x, y, w, h);
63 }

监听属性的变化:

1 // 只要监听的属性一改变,就会调用
2 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
3 {
4     if (_mainV.frame.origin.x > 0) { // 往右滑动,显示左边控件,隐藏右边控件
5         _rightV.hidden = YES;
6     }else if (_mainV.frame.origin.x < 0){ // 往左滑动,显示右边控件
7         _rightV.hidden = NO;
8     }
9 }

注意:KVO使用结束后一定要移除观察者

1 // 注意:当对象被销毁的时候,一定要注意移除观察者
2 - (void)dealloc
3 {
4     // 移除观察者
5     [_mainV removeObserver:self forKeyPath:XMGkeyPath(_mainV, frame)];
6 }

六:为界面添加一个单击手势,实现单击屏幕还原

1      // 给控制器的view添加一个点按
2
3      UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap)];
4
5      [self.view addGestureRecognizer:tap];

还原方法的实现:

 1 - (void)tap
 2 {
 3     if (_mainV.frame.origin.x != 0) {
 4         // 把_mainV还原最开始的位置
 5
 6         [UIView animateWithDuration:0.25 animations:^{
 7             _mainV.frame = self.view.bounds;
 8
 9         }];
10
11     }
12 }

下面就是最终的效果:

 

时间: 2024-10-11 16:50:34

简单的抽屉效果的相关文章

利用DrawerLayout实现简单的抽屉效果

前言,本篇文章是最基础的利用DrawerLayout实现抽屉效果,我也是尽量精简到了最高效的代码,后面我会贴出其他比较复杂的功能. 先看效果图 标题栏中的文字,会根据点击item的不同,而显示不同的样式. 直接上代码. 下面是activity_main的代码 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.andr

抽屉效果实现原理

实现一个简单的抽屉效果: 核心思想:KVO实现监听mainV的frame值的变化 核心代码: #import "ViewController.h" // @"frame" #define XMGkeyPath(objc, keyPath) @(((void)objc.keyPath, #keyPath)) // 在宏里面如果在参数前添加了#,就会把参数变成C语言字符串 // 获取屏幕的宽度 #define screenW [UIScreen mainScreen].

iOS开发——实用技术OC篇&amp;简单抽屉效果的实现

简单抽屉效果的实现 就目前大部分App来说基本上都有关于抽屉效果的实现,比如QQ/微信等.所以,今天我们就来简单的实现一下.当然如果你想你的效果更好或者是封装成一个到哪里都能用的工具类,那就还需要下一些功夫了,我们这里知识简单的介绍怎么去实现,不过一般我们开发都是找别人做好的,也没必要烂肺时间,除非你真的是大牛或者闲的蛋疼. 其实关于抽屉效果就是界面有三个View,其实一个主View其他两个分别是左边和右边的View,我们分别为他们添加手势,实现左右滑动显示对应的View. 一:所以,首先我们需

ios开发中超简单抽屉效果(MMDrawerController)的实现

ios开发中,展示类应用通常要用到抽屉效果,由于项目需要,本人找到一个demo,缩减掉一些不常用的功能,整理出一个较短的实例. 首先需要给工程添加第三方类库 MMDrawerController: 这里讲的实例只加入了左滑抽屉.右滑和左滑只是初始化时多添加一个右视图控制器,其他方法基本相同. 下面是用手势实现抽屉的拉出和收回 1.初始化跟视图控制器时,在AppDelegate中导入头文件 #import "MMDrawerController.h" 2.初始化方法先初始化左视图和中心视

iOS中 超简单抽屉效果(MMDrawerController)的实现

ios开发中,展示类应用通常要用到抽屉效果,由于项目需要,本人找到一个demo,缩减掉一些不常用的功能,整理出一个较短的实例. 首先需要给工程添加第三方类库 MMDrawerController: 这里讲的实例只加入了左滑抽屉.右滑和左滑只是初始化时多添加一个右视图控制器,其他方法基本相同. 下面是用手势实现抽屉的拉出和收回 1.初始化跟视图控制器时,在AppDelegate中导入头文件 #import "MMDrawerController.h" 2.初始化方法先初始化左视图和中心视

第三方抽屉效果

1.  抽屉效果的基本原理应用了父子视图的层级,视图的位置改变,动画,手势操作等主要知识点.熟练掌握基础知识并灵活运用,即可实现该效果. > 父子视图的层级: 在指定层级上插入子视图 [view insertSubView: atIndex:] > 视图位置的改变: 通过视图的frame,center属性调整 > 动画:可使用UIView或CALayer的动画,这里主要使用了UIView的动画方法 [UIView animateWithDuration:……. ] > 手势操作:主

抽屉效果的实现

抽屉效果 添加子视图 *   简单的滑动效果 * 监听控制器处理事件方法 * 获取x轴偏移量 * 改变主视图的frame *   利用KVO做视图切换 往左移动,显示右边,隐藏左边 往右移动,显示左边,隐藏右边 *  复杂的滑动效果,PPT讲解(根据手指每移动一点,x轴的偏移量算出当前视图的frame) 假设x移到320时,y移动到60,算出没移动一点x,移动多少y offsetY = offsetX * 60 / 320  手指每移动一点,x轴偏移量多少,y偏移多少 为了好看,x移动到320,

基于Qt的类似QQ好友列表抽屉效果的实现

前段时间在忙毕业设计,所以一直没有更新博客.今天答辩完以后,将对我的毕业设计进行模块展示,供Qt初学者进行参考. 毕业设计题目:Linux系统下基于Qt的局域网即时通信系统设计与实现 其中我有一个类似于QQ的好友列表,然后对好友可以进行分组管理,毕设中具体效果图如下: 网上查寻到的设计思路: 1.采用QToolBox的方式,虽然看起来有点样子,但是并不是我们所熟悉的好友列表,比如:http://blog.csdn.net/qianguozheng/article/details/6719074

实现侧边抽屉效果-YRSideViewController

在项目当中经常用到类似抽屉效果的页面转换,下面是简单的视图切换. 1,首先声明SideViewController,用来装所有要在屏幕中显示的控制器. 2,为SideViewController添加属性和方法,每个属性的作用都有注释.代码如下: // SliderViewController.h //普通动画的block typedef void(^RootViewMoveBlock) (UIView *rootView,CGRect orhinFrame,CGFloat xoffeset);