抽屉效果

在iOS中非常多应用都用到了抽屉效果,比如腾讯的QQ,百度贴吧…

———

1. 终于效果例如以下图所看到的

———

2.实现步骤

1.開始启动的时候。新建3个不同颜色的View的

1.设置3个成员属性。记录三种颜色的View

@property (nonatomic,weak) UIView* redView;
@property (nonatomic,weak) UIView* greenView;
@property (nonatomic,weak) UIView* blueView;

2.初始化3个View

- (void)setUpthreeViews
{
UIView *blueView = [[UIView alloc]initWithFrame:self.view.bounds];
blueView.backgroundColor = [UIColor blueColor];
[self.view addSubview:blueView];
_blueView = blueView; UIView *greenView = [[UIView alloc]initWithFrame:self.view.bounds];
greenView.backgroundColor = [UIColor greenColor];
[self.view addSubview:greenView];
_greenView = greenView; UIView *redView = [[UIView alloc]initWithFrame:self.view.bounds];
redView.backgroundColor = [UIColor redColor];
[self.view addSubview:redView];
_redView = redView;
}

2.实现滑动的效果

1.通过-(void)touchesMoved:(NSSet )touches withEvent:(UIEvent )event方法来获得当前点和初始点,从而计算出偏移量,然后计算redView的frame的值:

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
//获得当前点
CGPoint currentPoint = [touch locationInView:_redView];
//获得起点
CGPoint prePoint = [touch previousLocationInView:_redView];
//计算在x轴方向上的偏移量
CGFloat moveX = currentPoint.x - prePoint.x;
//然后通过在x轴上的偏移量。计算redView的frame
_redView.frame = [self framWithOffsetX:moveX];
}
  1. 假设x移到320时。y移动到60,算出每移动一点x,移动多少y

  2. offsetY = offsetX * 600 / 320 手指每移动一点,x轴偏移量多少,y偏移多少

  3. 为了好看。x移动到320。距离上下的高度须要保持一致。并且有一定的比例去缩放他的尺寸。

  4. touchMove仅仅能拿到之前的frame.当前的高度 = 之前的高度 * 这个比例

    缩放比例:当前的高度/之前的高度 (screenH - 2 * offsetY) / screenH。

    当前的宽度保持不变即可。
  5. y值,计算比較特殊,不能直接用之前的y,加上offsetY,往左滑动。主视图应该往下走,可是offsetX是负数,导致主视图会往上走。所以须要推断是左滑还是右滑
- (CGRect)framWithOffsetX:(CGFloat)offsetX
{
//计算在y轴方向上的偏移量
CGFloat offsetY = offsetX/SCREENWIDTH * MAXYOFFSET;
//依据y方向的偏移量计算缩放比例
CGFloat scale = (SCREENHEIGHT - 2*offsetY)/SCREENHEIGHT;
//假设x < 0表示左滑
if (_redView.frame.origin.x < 0) {
scale = (SCREENHEIGHT + 2*offsetY)/SCREENHEIGHT;
} CGRect frame = _redView.frame;
//计算滑动之后的frame
CGFloat height = frame.size.height*scale;
CGFloat width = frame.size.width;
CGFloat x = frame.origin.x + offsetX;
CGFloat y = (SCREENHEIGHT- height)* 0.5; return CGRectMake(x, y, width, height);
}

2.通过KVO来监听redView的frame的变化,从而推断redView是左滑还是右滑。往左移动。显示右边,隐藏左边 往右移动。显示左边。隐藏右边

- (void)viewDidLoad {
[super viewDidLoad];
[self setUpthreeViews]; // 利用KVO时刻监听_redView.frame改变
// Observer:谁须要观察
// KeyPath:监听的属性名称
// options: NSKeyValueObservingOptionNew监听这个属性新值
[_redView addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
} // 仅仅要监听的属性有新值的时候。仅仅要redView.frame一改变就会调用
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (self.redView.frame.origin.x > 0) {
_greenView.hidden = NO;
} else if(self.redView.frame.origin.x < 0){
_greenView.hidden = YES;
}
} // 当对象销毁的时候,一定要移除观察者
- (void)dealloc
{
[_redView removeObserver:self forKeyPath:@"frame"];
}

3.设置触摸结束的时候。redView的frame。假设redView側滑没有到屏幕的一半,则自己主动返回到初始位置。

假设超过屏幕的一半,则停留在一个新的位置


- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
CGFloat xPos = _redView.frame.origin.x;
//大于屏幕的一半进入新的位置
if (xPos > SCREENWIDTH*0.5) {
[UIView animateWithDuration:0.5 animations:^{
self.redView.frame = [self framWithBigThanX:ENDRIGHTX];
}];
return ;
}
//小于屏幕的一半。大于屏幕负一半的时候,则恢复到初始状态
if (xPos < SCREENWIDTH*0.5 && xPos > -SCREENWIDTH*0.5) {
[UIView animateWithDuration:0.5 animations:^{
self.redView.frame = [UIScreen mainScreen].bounds;
}];
return ;
}
//xPos < -SCREENWIDTH*0.5的时候,进入新的位置
[UIView animateWithDuration:0.5 animations:^{
self.redView.frame = [self framWithSmallThanX:ENDLEFTX];
}]; } - (CGRect)framWithBigThanX:(CGFloat)offsetX
{ CGFloat offsetY = offsetX/SCREENWIDTH * MAXYOFFSET;
CGFloat scale = (SCREENHEIGHT - 2*offsetY)/SCREENHEIGHT; CGFloat height = SCREENHEIGHT*scale;
CGFloat width = SCREENWIDTH;
CGFloat x = offsetX;
CGFloat y = (SCREENHEIGHT- height)* 0.5; return CGRectMake(x, y, width, height);
} - (CGRect)framWithSmallThanX:(CGFloat)offsetX
{
CGFloat offsetY = offsetX/SCREENWIDTH * MAXYOFFSET;
CGFloat scale = (SCREENHEIGHT + 2*offsetY)/SCREENHEIGHT; CGFloat height = SCREENHEIGHT*scale;
CGFloat width = SCREENWIDTH;
CGFloat x = offsetX;
CGFloat y = (SCREENHEIGHT- height)* 0.5; return CGRectMake(x, y, width, height);
}

iOS实现抽屉效果的更多相关文章

  1. iOS LeftMenu抽屉效果与ScrollView共存时的手势冲突

    公司有个项目,需要做左侧滑动,首页是ScrollView嵌套TableView.首页是一个ScrollView,所以当contentOffset是0.0的时候,无法直接滑动出抽屉效果,用户体验感非常差 ...

  2. ios开发抽屉效果的封装使用

    #import "DragerViewController.h" #define screenW [UIScreen mainScreen].bounds.size.width @ ...

  3. iOS开发之抽屉效果实现

    说道抽屉效果在iOS中比较有名的第三方类库就是PPRevealSideViewController.一说到第三方类库就自然而然的想到我们的CocoaPods,今天的博客中用CocoaPods引入PPR ...

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

    ios开发中,展示类应用通常要用到抽屉效果,由于项目需要,本人找到一个demo,缩减掉一些不常用的功能,整理出一个较短的实例. 首先需要给工程添加第三方类库 MMDrawerController: 这 ...

  5. 玩转iOS开发 - 简易的实现2种抽屉效果

    BeautyDrawer BeautyDrawer 是一款简单易用的抽屉效果实现框架,集成的属性能够对view 滑动缩放进行控制. Main features 三个视图,主视图能够左右滑动.实现抽屉效 ...

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

    ios开发中,展示类应用通常要用到抽屉效果,由于项目需要,本人找到一个demo,缩减掉一些不常用的功能,整理出一个较短的实例. 首先需要给工程添加第三方类库 MMDrawerController: 这 ...

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

    简单抽屉效果的实现 就目前大部分App来说基本上都有关于抽屉效果的实现,比如QQ/微信等.所以,今天我们就来简单的实现一下.当然如果你想你的效果更好或者是封装成一个到哪里都能用的工具类,那就还需要下一 ...

  8. 更好的抽屉效果(ios)

    昨天项目基本没啥事了,晚上早早的就回家了,躺在床上无聊地玩着手机(Android的),在清理系统垃圾时被一个“360手机助手”给吸引了, 其实我是被它的那个抽屉效果给吸引了,此时你也许会觉得我out了 ...

  9. iOS详解MMDrawerController抽屉效果(一)

      提前说好,本文绝对不是教你如何使用MMDrawerController这个第三方库,因为那太多人写了 ,也太简单了.这篇文章主要带你分析MMDrawerController是怎么实现抽屉效果,明白 ...

随机推荐

  1. 5.Project常用操作介绍

    Project常用操作介绍 1.项目浏览器 2.项目属性 Name:项目名称 Category:项目组织结构 Author:作者 Copyright:版权 Image:项目图标 Description ...

  2. javascript学习中自己对作用域和作用域链理解

    在javascript学习中作用域和作用域链还是相对难理解些,下面我关于javascript作用域和作用域链做一下详细介绍,给各位初学者答疑解惑. 首先我们介绍一下什么是作用域?  从字面上理解就是起 ...

  3. android系统源码下载

    ubuntu 安装git curl python 确保主目录下有一个 bin/ 目录,并且该目录包含在路径中: mkdir ~/bin PATH=~/bin:$PATH   下载 Repo 工具,并确 ...

  4. windows server 2008 不能执行bat

    服务器有一个bat脚本,需要自动或手工执行,之前一直运行OK,可是突然有一天自动或手动都不能执行了,查了半天,原来是因为另一个运维人把环境变量中path的值改了,%SystemRoot%\system ...

  5. Oracle 11g XE 与 Oracle SQL Developer 的配置与使用(重制版)

    Oracle 11g XE 与 Oracle SQL Developer 的配置与使用(重制版) 前提概要 项目上需求要适应Oracle数据库,当然这和某EF框架也有关. 因为Oracle 的表名和列 ...

  6. Java入门第一季——从此投身Java??

    找工作告一段落. 最后的工作呢,和java紧密相关,也是阴差阳错,不过都是软件开发,都好了,不过以后侧重点肯定是在java这边,php有机会还是一直学下去的,那么美的说~ Java开发第一季  一.简 ...

  7. C# 1.将整个文件夹复制到目标文件夹中 2.将指定文件复制到指定目标文件夹中

    ].Items.Clear(); string filePath = Application.StartupPath; string sourcePath = Path.Combine(filePat ...

  8. input左减右加

    <!DOCTYPE html><html lang="zh"><head> <meta charset="UTF-8" ...

  9. VMware ESXi定制版(OEM ISO)资源下载(包含5.1\5.5\6.0)

     一.VMware ESXi 5.1.0 update03 1.VMware-ESXi-5.1.0-Update3-2323236-hitachi-0400.iso(日立) 2.VMware-ESXi ...

  10. C#学习 第六节

    什么是类型(Type)? 类型在C#中的作用 C#语言的类型系统 变量.对象与内存 类型(Type):数据类型 性质相同的值得集合:内存:内部存储单元,计算机运行程序的空间:外存:扩展存储器,硬盘: ...