动画的抽屉效果
Posted J_维他命_M
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动画的抽屉效果相关的知识,希望对你有一定的参考价值。
添加三个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
效果图如下:
正常的屏幕
往左滑动
往右滑动
以上是关于动画的抽屉效果的主要内容,如果未能解决你的问题,请参考以下文章