IOS抽屉效果功能实现

抽屉效果功能实现

一、.h文件

@interface HMDrawViewController : UIViewController

@property (nonatomic, weak, readonly) UIView *mainView;
@property (nonatomic, weak, readonly) UIView *leftView;
@property (nonatomic, weak, readonly) UIView *rightView;

@end

二、.m文件

@interface HMDrawViewController ()

@property (nonatomic, assign) BOOL isDraging;
@end

@implementation HMDrawViewController

- (void)viewDidLoad
{
    // UIViewController
    [super viewDidLoad];
    // Do any additional setup after loading the view.
  
    // 1.添加子控件
    [self addChildView];
#warning 第三步 观察_mainView的frame改变
    // 2.监听
    /**
     *  给_mainView添加一个观察者
     *
     *  KeyPath:监听frame这个属性
     *
     *  options:监听新值的改变
     */
    [_mainView addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
  
}

// 当_mainView的frame属性改变的时候就会调用
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSLog(@"%@", NSStringFromCGRect(_mainView.frame));
   
    if (_mainView.frame.origin.x < 0) { // 往左移动
        // 显示右边
        _rightView.hidden = NO;
        // 隐藏左边
        _leftView.hidden = YES;
    }else if (_mainView.frame.origin.x > 0){ // 往右移动
        // 显示左边
        _rightView.hidden = YES;
        // 隐藏右边
        _leftView.hidden = NO;
       
    }
}

#warning 第一步
- (void)addChildView
{
    // left
    UIView *leftView = [[UIView alloc] initWithFrame:self.view.bounds];
    leftView.backgroundColor = [UIColor greenColor];
    [self.view addSubview:leftView];
    _leftView = leftView;
   
    // right
    UIView *rightView = [[UIView alloc] initWithFrame:self.view.bounds];
    rightView.backgroundColor = [UIColor blueColor];
    [self.view addSubview:rightView];
    _rightView = rightView;
   
    // mainView
    UIView *mainView = [[UIView alloc] initWithFrame:self.view.bounds];
    mainView.backgroundColor = [UIColor redColor];
    [self.view addSubview:mainView];
    _mainView = mainView;
}

#warning 第二步
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    // 获取UITouch对象
    UITouch *touch = [touches anyObject];
   
    // 获取当前点
    CGPoint currentPoint = [touch locationInView:self.view];
   
    // 获取上一个点
    CGPoint prePoint = [touch previousLocationInView:self.view];
   
    // x轴偏移量:当手指移动一点的时候,x偏移多少
    CGFloat offsetX = currentPoint.x - prePoint.x;
   
    // 设置当前主视图的frame
    _mainView.frame = [self getCurrentFrameWithOffsetX:offsetX];
   
   
    _isDraging = YES;
}
#warning 第四步
#define HMMaxY 60
// 当手指偏移一点,根据X轴的偏移量算出当前主视图的frame
- (CGRect)getCurrentFrameWithOffsetX:(CGFloat)offsetX
{
    CGFloat screenW = [UIScreen mainScreen].bounds.size.width;
    CGFloat screenH = [UIScreen mainScreen].bounds.size.height;
   
    // 获取y轴偏移量,手指每移动一点,y轴偏移多少
    CGFloat offsetY = offsetX * HMMaxY / screenW;
   
    CGFloat scale = (screenH - 2 * offsetY) / screenH;
   
    if (_mainView.frame.origin.x < 0) { // 往左边滑动
        scale = (screenH + 2 * offsetY) / screenH;
    }
   
    // 获取之前的frame
    CGRect frame = _mainView.frame;
    frame.origin.x += offsetX;
    frame.size.height = frame.size.height *scale;
    frame.size.width = frame.size.width *scale;
    frame.origin.y = (screenH - frame.size.height) * 0.5;
   
    return frame;
}

注意:

抽屉效果的固定的高度是写死的,可以定义一个宏,方便后期的维护。
算法:

offsetY = offsetX * 60 / 320
scale =  currentH / screenH
currentH  =  screenH – 2 * offsetY

x = frame. origin.x + offsetX
h = frame.size.height * scale
w = frame.size.weight * scale
y =( screenH – h ) * 0.5

#define HMRTarget 250
#define HMLTarget -220
/*
 _mainView.frame.origin.x > screenW * 0.5 定位到右边
  CGRectGetMaxX(_mainView.frame) < screenW * 0.5 定位到左边 -220
 
 */
// 定位
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    // 复位
    if (_isDraging == NO && _mainView.frame.origin.x != 0) {
        [UIView animateWithDuration:0.25 animations:^{
           
            _mainView.frame = self.view.bounds;
        }];
    }
    CGFloat screenW = [UIScreen mainScreen].bounds.size.width;
    CGFloat target = 0;
    if (_mainView.frame.origin.x > screenW * 0.5) { // 定位到右边
        target = HMRTarget;
    }else if (CGRectGetMaxX(_mainView.frame) < screenW * 0.5) { // 定位到左边
        target = HMLTarget;
    }
    [UIView animateWithDuration:0.25 animations:^{
       
        if (target) { // 在需要定位左边或者右边
           
            // 获取x轴偏移量
            CGFloat offsetX = target - _mainView.frame.origin.x;
           
            // 设置当前主视图的frame
            _mainView.frame = [self getCurrentFrameWithOffsetX:offsetX];
           
        }else{ // 还原
            _mainView.frame = self.view.bounds;
        }
    }];
    _isDraging = NO;
}

注意:

复位的时候,需要定义一个成员变量记录。
@end

注意:

知识点1:KVO观察者模式,给_mainView添加一个观察者, KeyPath:监听frame这个属性,options:监听新值的改变,当frame属性的值发生改变的时候就会调用下面这个方法。

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;

知识点2:抽屉效果的算法。

萌萌的IT人

时间: 2024-08-09 22:27:45

IOS抽屉效果功能实现的相关文章

抽屉效果功能实现

抽屉效果功能实现 一..h文件 @interface HMDrawViewController : UIViewController @property (nonatomic, weak, readonly) UIView *mainView; @property (nonatomic, weak, readonly) UIView *leftView; @property (nonatomic, weak, readonly) UIView *rightView; @end 二..m文件 @i

iOS抽屉效果和侧边菜单

iOS抽屉效果和侧边菜单 源码下载地址 1.效果演示 1. 抽屉效果演示 1. 侧边菜单演示 2.使用说明 构造方法 initialization /// 构造方法(左控制器 & 右控制器 & 背景图片) -(instancetype)initWithLeftController:(UIViewController *)leftController andMainController:(UIViewController *)mainController andRightController

iOS抽屉效果

源码下载 抽屉效果第三方类库下载 所需第三方类库下载 侧拉栏抽屉效果图         需要导入的头文件: #import "MMDrawerController.h" #import "MMExampleDrawerVisualStateManager.h" 代码实现: 首先需要创建三个试图控制器 //主视图 FirstViewController *firstVC = [[FirstViewController alloc] init]; //左边视图 Seco

IOS 抽屉效果

原创Blog,转载请注明出处 blog.csdn.net/hello_hwc 先看看Demo效果 视频链接如下 http://v.youku.com/v_show/id_XODc1OTQwODQ0.html 实现过程如下 1 新建一个基于单视图的工程.拖入两个ViewController,为了区分,在大纲中改为firstViewController 和 SecondViewController.沿着图中红线control+拖拽,在弹出的窗口中选择Show 2 选择Segue,为其添加Identi

猫猫学IOS(二十六)UI之iOS抽屉效果小Demo

猫猫分享,必须精品 素材代码地址:http://blog.csdn.net/u013357243/article/details/45305785 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243?viewmode=contents 先看效果 实现过程 第一步,把三个view设置好,还有颜色 #warning 第一步 - (void)addChildView { // left UIView *leftView = [[UIVie

(素材源码)猫猫学IOS(二十六)UI之iOS抽屉效果小Demo

猫猫分享,必须精品 素材代码地址:http://download.csdn.net/detail/u013357243/8635679 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243?viewmode=contents 先看效果 源码 NYDrawViewController.h // // NYDrawViewController.h // 06-抽屉效果 // // Created by apple on 14-9-1. /

简单的iOS抽屉效果

#define screenW [UIScreen mainScreen].bounds.size.width #import "ViewController.h" @interface ViewController () @property (nonatomic,strong)UIView * redView; @property (nonatomic,strong)UIView *yellowView; @property (nonatomic,strong)UIView *gre

抽屉效果学习

1, Ios左右菜单PPRevealSideviewController使用的一些心得 代码编写 http://blog.csdn.net/qjlhlh/article/details/8204563 2 stoaryBoard编写 iOS抽屉效果的demo http://cache.baiducontent.com/c?m=9f65cb4a8c8507ed4fece7631046893b4c4380146d96864968d4e414c42246071a27a2b820260d57938327

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

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