只要让控制器继承这个类,就可以带有抽屉效果.
#import <UIKit/UIKit.h>
@interface CQDragerViewController : UIViewController
// 只读的属性不能用self调用(没有set方法),只能用下划线调用
// 左边的View
@property (nonatomic, weak,readonly) UIView * leftView;
// 前面的View
@property (nonatomic, weak,readonly) UIView * mainView;
// 打开抽屉
- (void)open;
// 关闭抽屉
- (void)close;
@end
#import "CQDragerViewController.h"
@interface CQDragerViewController ()
@end
// 抽一个屏幕宽度的宏
#define screenW [UIScreen mainScreen].bounds.size.width
@implementation CQDragerViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 2. 添加子控件
[self addChildView];
// 3. 创建拖动手势
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
// 4. 添加拖动手势
[self.mainView addGestureRecognizer:pan];
// 创建点按手势
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(close)];
// 添加点按手势
[self.leftView addGestureRecognizer:tap];
}
#define target screenW * 0.8
// 打开抽屉
- (void)open
{
[UIView animateWithDuration:0.25 animations:^{
[self positionWithOffset:target];
CGRect frame = self.mainView.frame;
frame.origin.x = target;
self.mainView.frame = frame;
}];
}
/** 7. 复位 */
- (void)close
{
[UIView animateWithDuration:0.5 animations:^{
// 所有变化都清零;
self.mainView.transform = CGAffineTransformIdentity;
self.mainView.frame = self.view.bounds;
}];
}
/** 5. 根据偏移量计算当前mainView的位置 */
- (void)positionWithOffset:(CGFloat)offset
{
// 平移
CGRect frame = self.mainView.frame;
frame.origin.x += offset;
// 设置最大x为target
if (frame.origin.x > target) {
frame.origin.x = target;
}
self.mainView.frame = frame;
// 如果X小于0, 就不再移动 (防止反弹过度)
if (self.mainView.frame.origin.x <= 0 ) {
self.mainView.frame = self.view.bounds;
}
// 缩放
// 计算缩放比例 , 缩放最大值为0.3
// 当mainView的x等于屏幕宽度时,缩放比例达到最大
CGFloat scale = self.mainView.frame.origin.x * 0.3 / screenW;
scale = 1 - scale;
self.mainView.transform = CGAffineTransformMakeScale(scale, scale);
}
/** 6.实现手势方法(当手指拖动是调用) */
- (void)pan:(UIPanGestureRecognizer *)pan
{
// 获取偏移量
CGPoint transP = [pan translationInView:self.mainView];
// 对前面的View 做平移
// 根据偏移量计算当前mainView的位置
[self positionWithOffset:transP.x];
// 当mainView的x大于屏幕的宽度, 就自动跳到右边,否则自动跳到左边
// 判断手势的状态
if (pan.state == UIGestureRecognizerStateEnded) {
// 当手指松开时,判断x是否大于屏幕宽度的一半
if (self.mainView.frame.origin.x > screenW * 0.5) {
// 如果大于, 跳到右侧
// 计算偏移量
CGFloat offset = target - self.mainView.frame.origin.x;
// 设置跳转动画
[UIView animateWithDuration:0.5 animations:^{
[self positionWithOffset:offset];
}];
} else {
// 小于就复位
[self close];
}
}
// 滑动一次数据就清零
[pan setTranslation:CGPointZero inView:self.mainView];
}
/** 1. 添加子控件 */
- (void)addChildView
{
// 左边的View
UIView *leftView = [[UIView alloc] initWithFrame:self.view.bounds];
leftView.backgroundColor = [UIColor cyanColor];
[self.view addSubview:leftView];
// 只读的属性不能用self调用(没有set方法),只能用下划线调用
_leftView = leftView;
// 前面的View
UIView *mainView = [[UIView alloc] initWithFrame:self.view.bounds];
mainView.backgroundColor = [UIColor yellowColor];
[self.view addSubview:mainView];
_mainView = mainView;
}
@end
效果图: