抽屉效果

//
//  ViewController.m


#import "ViewController.h"

// 获取屏幕的宽度
#define screenW  [UIScreen mainScreen].bounds.size.width

@interface ViewController ()
@property(nonatomic,weak)UIView *leftV;
@property(nonatomic,weak)UIView *rightV;
@property(nonatomic,weak)UIView *mainV;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 添加子控件
    [self createChildView];
    
    // 添加pan手势
    UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
    [self.view addGestureRecognizer:panRecognizer];
    
    // 添加tap手势
    UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap)];
    [self.view addGestureRecognizer:tapRecognizer];
}

#pragma mark - tap的方法
- (void)tap
{
    if (self.mainV.frame.origin.x != 0) {
        [UIView animateWithDuration:0.25 animations:^{
            self.mainV.frame = self.view.bounds;
        }];
    }
}

#pragma mark - pan的方法
- (void)pan:(UIPanGestureRecognizer *)recognizer
{
    // 获取手势移动的位置
    CGPoint point = [recognizer translationInView:self.view];
    
    // 获取X轴心偏移量
    CGFloat offsetX = point.x;
    
    // 修改mainV的frame
    self.mainV.frame = [self frameWithOffsetX:offsetX];
    
    // 判断mainV的x是否大于0
    if (self.mainV.frame.origin.x > 0) { // 往右边滑动,隐藏rightV
        self.rightV.hidden = YES;
    }else if (self.mainV.frame.origin.x < 0){ // 往左边滑动,显示rightV
        self.rightV.hidden = NO;
    }
    
    // 复位
    [recognizer setTranslation:CGPointZero inView:self.view];
    
    // 判断当手势结束的时候,定位
    if (recognizer.state == UIGestureRecognizerStateEnded) {
        //  定位点
        CGFloat target = 0;
        
        if (self.mainV.frame.origin.x > screenW * 0.5) {
            // 定位到右边
            target = 220;
        }else if (CGRectGetMaxX(self.mainV.frame) < screenW * 0.5 ){
            target = -200;
        }
        
        // 获取X轴偏移量
        CGFloat offsetX = target - self.mainV.frame.origin.x;
        
        // 动画改变frame
        [UIView animateWithDuration:0.25 animations:^{
           self.mainV.frame = target == 0 ? self.view.bounds : [self frameWithOffsetX:offsetX];
        }];
    }

}

/**
 *  根据offsetX计算mainV的frame
 */
#define kMaxY 80
- (CGRect)frameWithOffsetX:(CGFloat)offsetX
{
    /*
     手指往右移动,视图X轴也要往右移动(x++)
     同时Y轴向下移动(y++),尺寸缩放(按比例)
     */
    
    // 获取上一次的frame
    CGRect frame = self.mainV.frame;
    // 获取上一次的高度
    CGFloat preH = frame.size.height;
    // 获取上一次的宽度
    CGFloat preW = frame.size.width;
    
    // 获取屏幕的高度
    CGFloat screenH = [UIScreen mainScreen].bounds.size.height;
    
    // X轴每平移一点,Y轴需要移动
    CGFloat offsetY = offsetX * kMaxY / screenW;
    
    // 获取当前的高度
    CGFloat currentH = frame.size.height - offsetY * 2;
    if (frame.origin.x < 0) { // 往左边滑动
        currentH = frame.size.height + offsetY * 2;
    }
    
    // 获取尺寸的缩放比例
    CGFloat scale = currentH / preH;
    
    // 获取当前的宽度
    CGFloat currentW = preW * scale;
    
    // 计算x
    frame.origin.x += offsetX;
    // 计算y
    frame.origin.y = (screenH - currentH) / 2;
    
    frame.size.height = currentH;
    frame.size.width = currentW;
    
    return frame;
}

#pragma mark - 添加子控件
/**
 *  创建子控件
 */
- (void)createChildView
{
    UIView *leftV = [[UIView alloc] initWithFrame:self.view.bounds];
    leftV.backgroundColor = [UIColor orangeColor];
    [self.view addSubview:leftV];
    self.leftV = leftV;
    
    UIView *rightV = [[UIView alloc] initWithFrame:self.view.bounds];
    rightV.backgroundColor = [UIColor blueColor];
    [self.view addSubview:rightV];
    self.rightV = rightV;
    
    UIView *mainV = [[UIView alloc] initWithFrame:self.view.bounds];
    mainV.backgroundColor = [UIColor redColor];
    [self.view addSubview:mainV];
    self.mainV = mainV;
}

@end

演示:


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值