#import "DragerViewController.h"

#define screenW [UIScreen mainScreen].bounds.size.width

@interface DragerViewController ()

/** <#注释#> */
@property (nonatomic, weak) UIView *leftV;
@property (nonatomic, weak) UIView *rightV;
@property (nonatomic, weak) UIView *mainV; @end @implementation DragerViewController - (void)viewDidLoad {
[super viewDidLoad]; //1:添加子控件
[self setUp]; //2:添加拖拽平移手势
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
[self.mainV addGestureRecognizer:pan]; //3:给控制器的View添加点按手势:给控制器添加手势,无论点击的是上部的view还是底部的view,控制器都会去响应事件。
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap)];
[self.view addGestureRecognizer:tap];
} #pragma mark -- tap轻击事件,让抽屉复位
- (void)tap{
//让MainV复位 [UIView animateWithDuration:0.5 animations:^{
self.mainV.frame = self.view.bounds;
}]; } #pragma mark -- 拖拽平移手势事件
/**
* 1:像是#define 和 static等都可以在@implementation之上定义,或是之下定义均可以
*/
#define targetR 275
#define targetL -275
- (void)pan:(UIPanGestureRecognizer *)pan{ /**
1:为什么不使用transform,是因为我们还要去修改高度,使用transform,只能修改,x,y,累加形变(y方向不需要平移)
self.mainV.transform = CGAffineTransformTranslate(self.mainV.transform, transP.x, 0);
2:修改控件的frame:1:可以用frame去修改 2:可以利用transform去修改,旋转,平移,缩放,累加形变和非累加形变,清空形变,类型为CGAffineTransform类型
3:将修改frame的方法封装起来,外界传一个x值,返回一个修改后的frame的值。
*
*/ //1:获取偏移量
CGPoint transP = [pan translationInView:self.mainV];
self.mainV.frame = [self frameWithOffsetX:transP.x]; /**
*1:通过x值判断是向左平移还是向右平移:大于0向右平移,小于0向左平移。通过显示和隐藏来控制左右到底显示哪个view
2:view添加的顺序,mainView在最上层,均添加到了self.view上
*
*/ //2:判断拖动的方向,显示不同的view
if(self.mainV.frame.origin.x > ){
//向右
self.rightV.hidden = YES;
}else if(self.mainV.frame.origin.x < ){
//向左
self.rightV.hidden = NO;
} //3:当手指松开时,做自动定位.
CGFloat target = ;
if (pan.state == UIGestureRecognizerStateEnded) { if (self.mainV.frame.origin.x > screenW * 0.5 ) {
//1判断在右侧
//当前View的x有没有大于屏幕宽度的一半,大于就是在右侧
target = targetR;
}else if(CGRectGetMaxX(self.mainV.frame) < screenW * 0.5){
//2.判断在左侧
//当前View的最大的x有没有小于屏幕宽度的一半,小于就是在左侧
target = targetL;
} //计算当前mainV的frame.
CGFloat offset = target - self.mainV.frame.origin.x;
[UIView animateWithDuration:0.5 animations:^{ self.mainV.frame = [self frameWithOffsetX:offset];
}]; } //4:复位:进行复位操作的目的是:让其根据上一次的平移进行平移而不是每次都根据初始位置进行平移
[pan setTranslation:CGPointZero inView:self.mainV]; } #define maxY 100
#pragma mark --根据偏移量计算MainV的frame
- (CGRect)frameWithOffsetX:(CGFloat)offsetX { //当进行拖拽平移的时候,更改mainView的的x值和高度
/**
* 1:x值是累加形变的,所以是frame.origin.x += offsetX
2:求最大y值,设最大的y值为100,用当前的x值乘以最大y值与屏幕的宽度比
3:求拖拽平移的高度:屏幕高度 - 2倍的最大的y值,并返回frame
4:fabs:对计算结果取绝对值,因为当向左滑动的时候,x值为负数
*/ //1:x值
CGRect frame = self.mainV.frame;
frame.origin.x += offsetX; //当拖动的View的x值等于屏幕宽度时,maxY为最大,最大为100
// 375 * 100 / 375 = 100
//对计算的结果取绝对值
CGFloat y = fabs( frame.origin.x * maxY / screenW);
frame.origin.y = y; //2:屏幕的高度减去两倍的Y值
frame.size.height = [UIScreen mainScreen].bounds.size.height - ( * frame.origin.y); return frame;
} /**
* 添加view:此时的view以属性修饰,用weak修饰,self.leftV = leftV;可以写在addSubview之前或是之后,都能保证weak指向的对象不会被销毁。
*/ - (void)setUp{ //leftV
UIView *leftV = [[UIView alloc] initWithFrame:self.view.bounds];
leftV.backgroundColor = [UIColor blueColor];
self.leftV = leftV;
[self.view addSubview:leftV];
//rightV
UIView *rightV = [[UIView alloc] initWithFrame:self.view.bounds];
rightV.backgroundColor = [UIColor greenColor];
self.rightV = rightV;
[self.view addSubview:rightV];
//mianV
UIView *mainV = [[UIView alloc] initWithFrame:self.view.bounds];
mainV.backgroundColor = [UIColor redColor];
self.mainV = mainV;
[self.view addSubview:mainV];
}
/**
* 思路总结: 1:具体思路:1:自定义控制器,在控制器的view上分别添加左右抽屉和mainview,并给mainView添加平移手势,给self.view添加轻击手势,虽然点击的是mainView或是其他的view,但是响应事件的就是self.view 2:1:在平移手势的方法中,获得平移的距离,此时改变mainView的frame有两种方法,transform累加形变或是直接更改frame,使用transform不能设置其高度,所以用更改frame的方法。将更改frame的方法封装起来外界传入偏移的x值,返回一个mainView的frame。2:1:设置frame的x值,x值是累加形变的,frame.origin.x += offsetX;并根据x值平移的比例计算y值并计算高度, CGFloat y = fabs( frame.origin.x * maxY / screenW);frame.origin.y = y;因为要考虑向左或是向右平移所以取绝对值,设置y值,并计算高度返回frame。3:在根据判断向左还是向右平移来显示或隐藏左右抽屉,(根据x值的正负来判断)4:再判断手指离开时自动复位,根据x值和最大x值和屏幕宽度的一半进行比较,来传入x值设置frame,最后将唯一归0,为了基于上次平移来计算 3:点击抽屉或是mainView来使其复原。就直接更改mainView的frame就可以了 */ @end

二:抽屉效果的使用:

1:当我们用别人封装好的框架时,若不是不符合需求尽量不要修改源代码,采用继承的方式去利用别人封装好的框架

2:当我们已经在xib或是storyboard中拖进去控件的时候,此时又新建立了一个类,想与xib或是storyboard中的拖进去的控件相关联,此时可以在xib或是storyboard中去设置:

3:对于左右抽屉页面的业务逻辑处理一般不交给view处理,复杂的业务逻辑都交给控制器去处理,所以左右抽屉的view都添加控制器的view,而且当控制器的view互为父子关系时,则控制其器也应该互为父子关系

4:当我们去封装一个框架的时候,不希望外界去更改暴露的接口时,可以用readonly属性修饰。则在自身类的.m中不能用self去访问该属性变量只能用下划线的成员变量去赋值。且在外部既不能利用self去访问下划线的成员变量,也不能用下划线成员变量去访问。

ios开发抽屉效果的封装使用的更多相关文章

  1. iOS实现抽屉效果

    抽屉效果 在iOS中非常多应用都用到了抽屉效果,比如腾讯的QQ,百度贴吧- --- 1. 终于效果例如以下图所看到的 --- 2.实现步骤 1.開始启动的时候.新建3个不同颜色的View的 1.设置3 ...

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

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

  3. iOS开发之蓝牙业务封装

    因为公司做智能家居开发,有很多蓝牙的智能硬件.因此项目中经常需要和蓝牙打交道.为此为了提高开发效率,就把蓝牙的公共业务进行了封装. 本文将对封装的思路做一个简单的阐述. 首先我们需要一个头文件.在这个 ...

  4. iOS开发 弹簧效果

    #import "DDJelloView.h" #define SYS_DEVICE_WIDTH    ([[UIScreen mainScreen] bounds].size.w ...

  5. iOS开发短信验证码封装 方便好用

    ---恢复内容开始--- 1.RootViewControler//  Copyright © 2016年 Chason. All rights reserved.// #import "V ...

  6. iOS开发——UI篇&提示效果

    提示效果 关于iOS开发提示效果是一个很常见的技术,比如我们平时点击一个按钮,实现回馈,或者发送网络请求的时候! 技术点: 一:View UIAlertView UIActionSheet 二:控制器 ...

  7. 文顶顶iOS开发博客链接整理及部分项目源代码下载

    文顶顶iOS开发博客链接整理及部分项目源代码下载   网上的iOS开发的教程很多,但是像cnblogs博主文顶顶的博客这样内容图文并茂,代码齐全,示例经典,原理也有阐述,覆盖面宽广,自成系统的系列教程 ...

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

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

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

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

随机推荐

  1. 洛谷P1043 数字游戏

    题目描述 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易.游戏是这样的,在你面前有一圈整数(一共n个),你要按顺序将其分 ...

  2. JavaScript的字符串、数组以及DOM操作总结

    (一)JavaScript字符串操作 JavaScript的字符串就是用' '或" "括起来的字符表示,日常的学习中有时候需要对字符串进行相关的操作.例如要获取字符串某个指定位置的 ...

  3. MariaDB 安装 (YUM)

    在CentOS 7.0安装MariaDB的数据库,在这里记录下安装过程,以便以后查看. 1. 安装MariaDB 安装命令 yum -y install mariadb mariadb-server ...

  4. spring+mybatis+Atomikos JTA事务配置说明

    一.概览 Atomikos是一个公司名字,旗下最著名的莫过于其Atomikos的事务管理器产品.产品分两个:一个是开源的TransactionEssentials,一个是商业的ExtremeTrans ...

  5. Android学习之图片压缩,压缩程度高且失真度小

    曾经在做手机上传图片的时候.直接获取相机拍摄的原图上传,原图大小一般1~2M.因此上传一张都比較浪费资源,有些场景还须要图片多张上传,所以近期查看了好多前辈写的关于图片处理的资料.然后试着改了一个图片 ...

  6. 9.Spring Boot实战之配置使用Logback进行日志记录

    转自:https://blog.csdn.net/meiliangdeng1990/article/details/54300227 Spring Boot实战之配置使用Logback进行日志记录 在 ...

  7. HDU 4508 湫湫系列故事——减肥记I (2013腾讯编程马拉松初赛第一场)

    http://acm.hdu.edu.cn/showproblem.php?pid=4508 题目大意: 给定一些数据. 每组数据以一个整数n开始,表示每天的食物清单有n种食物.  接下来n行,每行两 ...

  8. app 自动化测试 Appium+Java可以运行的代码

    地址:http://www.cnblogs.com/sunny-sl/p/6520465.html

  9. 【河南省多校脸萌第六场 A】巴什博弈?

    [链接]http://acm.nyist.me/JudgeOnline/problem.php?cid=1013&pid=5 [题意] 在这里写题意 [题解] 0..a-1 YES a..a+ ...

  10. amazeui学习笔记--css(常用组件11)--分页Pagination

    amazeui学习笔记--css(常用组件11)--分页Pagination 一.总结 1.分页使用:还是ul包li的形式: 分页组件,<ul> / <ol> 添加 .am-p ...