动画的抽屉效果

添加三个View

//
//  ViewController.m
//  UISenior17_抽屉效果
//
//  Created by lanou3g on 16/5/27.
//  Copyright © 2016年 张明杰. All rights reserved.
//

#import "ViewController.h"
//frame
#define XMGkeyPath(objc, keyPath) @(((void)objc.keyPath, #keyPath))
//获取屏幕的宽度
#define screenW [UIScreen mainScreen].bounds.size.width
//获取屏幕的高度
#define screenH [UIScreen mainScreen].bounds.size.height

#define targetR 300
#define targetL -200

#define XMGMaxY 100
@interface ViewController ()
@property (strong, nonatomic) IBOutlet UIView *mainV;

@property (weak, nonatomic) IBOutlet UIView *leftV;
@property (weak, nonatomic) IBOutlet UIView *ringhtV;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    [self setUpAllChildView];

    //添加拖拽手势
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];

    [_mainV addGestureRecognizer:pan];

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

    //给控制器的view添加一个点按

    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap)];
    [self.view addGestureRecognizer:tap];
}

- (void)setUpAllChildView{
    //left
    UIView *leftV = [[UIView alloc] initWithFrame:self.view.bounds];
      leftV.backgroundColor = [UIColor greenColor];
    [self.view addSubview:leftV];
    _leftV = leftV;

    // right
  UIView *rightV = [[UIView alloc] initWithFrame:self.view.bounds];
    rightV.backgroundColor = [UIColor blueColor];
         [self.view addSubview:rightV];
         _ringhtV = rightV;

         // main
         UIView *mainV = [[UIView alloc] initWithFrame:self.view.bounds];
         mainV.backgroundColor = [UIColor redColor];
         [self.view addSubview:mainV];
        _mainV = mainV;
}

//获取手势的偏移量

- (void)pan:(UIPanGestureRecognizer *)pan {

    //获取手势的偏移量
    CGPoint transP = [pan translationInView:_mainV];
    //获取x轴的偏移量,相对于上一次

    CGFloat offsetX = transP.x;
    //修改最新的main.frame
 _mainV.frame = [self frameWithOffsetX:offsetX];
    //复位
    [pan setTranslation:CGPointZero inView:_mainV];
    //判断下当前手指没有抬起,表示手势结束
    if (pan.state == UIGestureRecognizerStateEnded) {
        //手指抬起,定位// x>屏幕的一半,定位到右边某个位置
        CGFloat target = 0;
        if (_mainV.frame.origin.x > screenW*0.5) {
            target = targetR;
        } else if (CGRectGetMaxX(_mainV.frame) < screenW *0.5) {
            //最大的x<屏幕一半的时候,定义到左边某个位置
            target = targetL;

        }
        //获取x轴的偏移量
        CGFloat offsetX = target - _mainV.frame.origin.x;
        [UIView animateWithDuration:0.25 animations:^{
            _mainV.frame = [self frameWithOffsetX:offsetX];
        }];
    }

}
//给定一个x轴的偏移量计算下最先的main frame
- (CGRect)frameWithOffsetX:(CGFloat)offsetX {
    //获取当前main的frame

    CGRect frame = _mainV.frame;
    //计算当前的x.y.w.h
    //获取最新的x

    CGFloat x = frame.origin.x + offsetX;
    //获取最新的y
    CGFloat y = x /screenW *XMGMaxY;
    //当用户往左边移动的时候,_main.x < 0,y需要增加,为正
    if (frame.origin.x < 0) {
        y = -y;
    }

    //获取最新的h
    CGFloat h = screenH - 2 *y;
    //获取缩放比例

    CGFloat scale = h / screenH;
    //获取最新的w
    CGFloat w = screenW *scale;

    return CGRectMake(x, y, w, h);

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

    }else  if (_mainV.frame.origin.x < 0){
        _ringhtV.hidden = NO;
    }
}
- (void)dealloc {
    //移除观察者
    [_mainV removeObserver:self forKeyPath:XMGkeyPath(_mainV, frame)];

}

- (void)tap {
    if (_mainV.frame.origin.x != 0) {
        //把_mainV还原最开始的位置
        [UIView animateWithDuration:0.25 animations:^{
            _mainV.frame = self.view.bounds;
        }];
    }
}

@end

效果图如下:

  正常的屏幕

往左滑动

往右滑动

时间: 2024-10-18 20:44:44

动画的抽屉效果的相关文章

第三方抽屉效果

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

Android-自定义滑动菜单(抽屉效果)

在Andoird使用Android自带的那些组件,像SlidingDrawer和DrawerLayout都是抽屉效果的菜单,但是在项目很多要实现的功能都收到Android这些自带组件的限制,导致很难完成项目的需求,自定义的组件,各方面都在自己的控制之下,从而根据需求做出调整.想要实现好的效果,基本上都的基于Android的OnTouch事件自己实现响应的功能. 首先,给大家先看一下整体的效果: 滑动的加速度效果都是有的,具体的体验,只能安装后才能查看. 接下来,看代码: 代码从MainActiv

iOS侧拉栏抽屉效果Demo

源码下载 侧拉栏抽屉效果Demo 需要导入第三方的类库如下: 抽屉效果所需第三方类库下载 效果:既可以两侧都实现抽屉效果也可只实现左侧栏或者右侧栏的抽屉效果                            关于抽屉效果主要是AppDelegate的代码 AppDelegate.h文件代码: <span style="font-size:18px;"><span style="font-size:18px;">#import <UI

实现侧边抽屉效果-YRSideViewController

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

Android---62---DrawerLayout实现抽屉效果

如何实现android中的抽屉效果? 1.创建xml文件 其根视图是<android.support.v4.widget.DrawerLayout/> 这个xml分为两部分,一部分是主要内容的视图,一部分是抽屉的视图. 主要内容视图一般是FrameLayout,一定要是DrawerLayout的第一个视图,其高度和父视图的高度匹配. 抽屉视图一般是ListView,在写抽屉视图的时候要注意 1.宽度一般要小于320dp 2.android:layout_gravity属性是确定抽屉的位置 当该

iOS抽屉效果

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

抽屉效果的实现原理

@property (nonatomic, strong)UIImageView *choytiimage; @property (nonatomic, strong)UIButton *choutibutton; @property (nonatomic, strong)UIButton *button; @property (nonatomic, strong)UILabel *label; @property (nonatomic, strong)UILabel *label1; @pro

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

#import "DragerViewController.h" #define screenW [UIScreen mainScreen].bounds.size.width @interface DragerViewController () /** <#注释#> */ @property (nonatomic, weak) UIView *leftV; @property (nonatomic, weak) UIView *rightV; @property (non

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

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