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

#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 > 0){
        //向右
        self.rightV.hidden = YES;
    }else if(self.mainV.frame.origin.x < 0){
        //向左
        self.rightV.hidden = NO;
    }

    //3:当手指松开时,做自动定位.
    CGFloat target = 0;
    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 - (2 * 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去访问下划线的成员变量,也不能用下划线成员变量去访问。

时间: 2024-10-11 10:57:45

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

iOS开发项目篇—36封装微博业务

iOS开发项目篇—36封装微博业务 一.简单说明 1.请求参数面向模型 2.请求结果面向模型 3.对控制器来说应该屏蔽业务细节.不让控制器关心(知道)业务细节,它只需要知道自己在做某个业务 @通过一个专门的业务处理类:处理微博业务细节 说明: 业务:加载新的微博首页数据 实现:给新浪服务器发送一个GET请求 业务:加载更多的首页微博数据 实现1:给新浪服务器发送一个GET请求 实现2:去沙盒中加载以前离线缓存的微博数据  二.实现 1.新建一个微博业务处理类,继承自NSObject 微博业务处理

iOS开发项目篇—37封装其他业务

iOS开发项目篇—37封装其他业务 一.简单说明 项目分层的步骤: (1)新建一个模型类封装请求参数 (2)新建一个模型类封装请求结果(返回结果) (3)新建一个业务类封装专一的业务 二.获得用户信息业务的封装 (1)新建一个模型类封装请求参数 查看新浪官方获取用户信息需要哪些请求参数: 封装请求参数的类的代码设计: YYUserInfoParam.h文件 1 // 2 // YYUserInfoParam.h 3 // 4 5 #import <Foundation/Foundation.h>

iOS开发项目篇—35封装网络请求

iOS开发项目篇—35封装网络请求 一.简单说明 1.分析项目对网路请求(AFN框架)的依赖 项目中,多个控制器都使用了AFN框架发送网络请求,如果AFN2.0存在重大BUg,或者是升级至3.0版本,那么对于整个项目都是及其危险的,所有用到AFN的地方都需要做出相应的修改. 另外,如果现在要求不再使用AFN框架,而是使用一个新的框架,那么有关AFN的依赖所关联的所有代码都需要重新来过. 如果把afn这个第三方框架从项目中删除的话,那么项目就相当于作废了,这就是项目对第三方框架的强依赖的体现. 说

iOS实现抽屉效果

抽屉效果 在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.

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

公司有个项目,需要做左侧滑动,首页是ScrollView嵌套TableView.首页是一个ScrollView,所以当contentOffset是0.0的时候,无法直接滑动出抽屉效果,用户体验感非常差.思考了一下还是手势的问题. 于是将ScrollView单独分了出来,重写了 - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer方法 在左滑动的时候return NO即可. #import "My

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

---恢复内容开始--- 1.RootViewControler//  Copyright © 2016年 Chason. All rights reserved.// #import "ViewController.h"#import "MessageCordView.h"//手机屏幕的宽和高#define kScreenWidth [UIScreen mainScreen].bounds.size.width#define KScreenHeight [UISc

iOS开发——UI篇&amp;提示效果

提示效果 关于iOS开发提示效果是一个很常见的技术,比如我们平时点击一个按钮,实现回馈,或者发送网络请求的时候! 技术点: 一:View UIAlertView UIActionSheet 二:控制器 UIAlertController 三:第三方库 SVProgressHUD MBProgressHUD 下面是主界面: 首先我们来看看系统自带的一些提示框(View) 一::UIAlertView 1:创建UIalertView(这里只说纯代码创建的方式) 1 UIAlertView *aler

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

文顶顶iOS开发博客链接整理及部分项目源代码下载 网上的iOS开发的教程很多,但是像cnblogs博主文顶顶的博客这样内容图文并茂,代码齐全,示例经典,原理也有阐述,覆盖面宽广,自成系统的系列教程却很难找.如果你是初学者,在学习了斯坦福iOS7公开课和跟着文顶顶的博客做项目之后,最快只需要2个月时间,就基本可以独立完成iOS App的开发工作.有经验的开发者也可以在该博客中寻找代码片段进行学习借鉴,必有所收获. 在此也向@文顶顶 表示严重感谢! 由于文顶顶博客博文繁多,每次找文章需要频繁的翻页,

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

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