iOS中的抽屉效果

在如今的App中很多应用都会有抽屉效果的身影,如比较热门的网易新闻和腾讯QQ。实际开发中实现抽屉效果主要是靠控制器之间的不断切换,来展示不同的View,已达到不同效果的展示。不过在本文中,主要是通过几个简单的UIView来模拟一下抽屉效果。下面就先上代码。
首先是创建3个不同的UIView:

// 创建三个view
    // 蓝色
    UIView *blueView = [[UIView alloc] initWithFrame:self.view.bounds];
    blueView.backgroundColor = [UIColor blueColor];
    [self.view addSubview:blueView];
    self.blueView = blueView;

    // 橙色
    UIView *orangeView = [[UIView alloc] initWithFrame:self.view.bounds];
    orangeView.backgroundColor = [UIColor orangeColor];
    [self.view addSubview:orangeView];
    self.orangeView = orangeView;

    // 红色
    UIView *redView = [[UIView alloc] initWithFrame:self.view.bounds];
    redView.backgroundColor = [UIColor redColor];
    [self.view addSubview:redView];
    self.redView = redView;

同时把创建的3个UIView变成控制器的属性,方便之后改变其Frame.

使用KVO来监听redView的Frame属性的变化:

// 使用kvo监听红色view frame值的改变
    [self.redView addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];

第二步,实现触摸事件的相关方法

// 当手指在屏幕上移动的时候调用
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    self.draging = YES;
    // 获得触摸对象
    UITouch *touch = [touches anyObject];
    // 获得上一个触摸点的位置
    CGPoint previousPoint = [touch previousLocationInView:self.view];
    // 获得当前触摸点的位置
    CGPoint currentPoint = [touch locationInView:self.view];

    // 计算x方向上的偏移量
    CGFloat offsetX = currentPoint.x - previousPoint.x;
    // 根据x方向的偏移量计算红色view的frame
    self.redView.frame = [self rectWithOffsetX:offsetX];

}
// 当手指离开屏幕的时候调用
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    if (!self.draging && self.redView.frame.origin.x != 0) {
        [UIView animateWithDuration:0.15 animations:^{
            // 恢复到最初状态
            self.redView.frame = self.view.bounds;
        }];
        return;
    }
    // 获得屏幕的宽度
    CGFloat screenW = [UIScreen mainScreen].bounds.size.width;
    // 获得红色view的x值
    CGFloat redViewX = self.redView.frame.origin.x; // 250
    if(redViewX > screenW * 0.5) {
        // 如果大于屏幕的一半
        redViewX = CZMaxX;
    } else if(redViewX < -(screenW * 0.5)){ // -200 -300
        // 如果红色view的x值小于屏幕宽度的一半
        redViewX = CZMinX;
    }
    // 计算x方向的偏移量
    CGFloat offsetX = redViewX - self.redView.frame.origin.x; // 0
    [UIView animateWithDuration:0.15 animations:^{
        self.redView.frame = (offsetX == 0)? self.view.bounds:[self rectWithOffsetX:offsetX];
    }];

    self.draging = NO;
}
/**
 *  根据x方向的偏移量计算红色view的frame
 */
- (CGRect)rectWithOffsetX:(CGFloat)offsetX {
    // 获得屏幕的宽度
    CGFloat screenW = [UIScreen mainScreen].bounds.size.width;
    CGFloat screenH = [UIScreen mainScreen].bounds.size.height;
    // 计算y方向的偏移量
    CGFloat offsetY = offsetX * CZMaxTopMargin / screenW;
    if (self.redView.frame.origin.x < 0) {
        offsetY *= -1;
    }
    // 获得当前红色view的frame
    CGRect frame = self.redView.frame;
    frame.origin.x += offsetX;
    frame.origin.y += offsetY;
    frame.size.height = screenH - 2 * frame.origin.y;

    return frame;
}

使用到的宏定义:

/**
 * 红色view最大的y值
*/
#define CZMaxTopMargin 100
/**
 *  红色view最大的x值
 */
#define CZMaxX 250

/**
 *  红色view最小的x值
 */
#define CZMinX -300

程序运行显示的UIView界面:
程序开始运行的界面

鼠标向右滑动的效果图:
这里写图片描述

鼠标向左滑动的效果图:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值