抽屉效果的简单实现

如今的应用大多会采用抽屉效果来进行实现,下边附上一段简单的抽屉效果的实现代码,记录一下。当然要实现抽屉效果还可以有很多更简单的方式(比如使用第三方框架:MMDrawerController gitHub地址https://github.com/mutualmobile/MMDrawerController)。但了解一下底层代码的具体实现也是很有必要的。

1,首先定义一些可能会用到的宏

//抽屉顶部距离 底部一样
#define WNXScaleTopMargin 35
//app的高度
#define WNXAppWidth ([UIScreen mainScreen].bounds.size.width)
//app的宽度
#define WNXAppHeight ([UIScreen mainScreen].bounds.size.height)
//抽屉拉出来右边剩余比例
#define WNXZoomScaleRight 0.14

2,添加拖拽手势

  //添加手势
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
    pan.delegate = self;
    [self.view addGestureRecognizer:pan];

设置一个记录当前显示的控制器

//记录当前显示的控制器,用于添加手势拖拽
@property (nonatomic, weak) WNXViewController *showViewController;

3,实现拖拽手势。具体实现方式请看注释

#pragma mark - 手势
//拖拽Action
- (void)pan:(UIPanGestureRecognizer *)pan
{
    CGFloat moveX = [pan translationInView:self.view].x;

    //缩放的最终比例值
    CGFloat zoomScale = (WNXAppHeight - WNXScaleTopMargin * 2) / WNXAppHeight;

    //X最终偏移距离
    CGFloat maxMoveX = WNXAppWidth - WNXAppWidth * WNXZoomScaleRight;

    //没有缩放时,允许缩放
    if (self.showViewController.isScale == NO) {

        if (moveX <= maxMoveX + 5 && moveX >= 0) {

            //获取X偏移XY缩放的比例
            CGFloat scaleXY = 1 - moveX / maxMoveX * WNXZoomScaleRight;

            CGAffineTransform transform = CGAffineTransformMakeScale(scaleXY, scaleXY);

            self.showViewController.navigationController.view.transform = CGAffineTransformTranslate(transform, moveX / scaleXY, 0);
        }

        //当手势停止的时候,判断X轴的移动距离,停靠
        if (pan.state == UIGestureRecognizerStateEnded) {
            //计算剩余停靠时间
            if (moveX >= maxMoveX / 2) {
                CGFloat duration = 0.5 * (maxMoveX - moveX)/maxMoveX > 0 ? 0.5 * (maxMoveX - moveX)/maxMoveX : -(0.5 * (maxMoveX - moveX)/maxMoveX);
                if (duration <= 0.1) duration = 0.1;
                //直接停靠到停止的位置
                [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
                    CGAffineTransform tt = CGAffineTransformMakeScale(zoomScale, zoomScale);
                    self.showViewController.navigationController.view.transform = CGAffineTransformTranslate(tt, maxMoveX , 0);

                } completion:^(BOOL finished) {
                    //将状态改为已经缩放
                    self.showViewController.isScale = YES;
                    //手动点击按钮添加遮盖
                    [self.showViewController rightClick];
                }];

            } else  {//X轴移动不够一半 回到原位,不是缩放状态

                [UIView animateWithDuration:0.2 animations:^{

                    self.showViewController.navigationController.view.transform = CGAffineTransformIdentity;

                } completion:^(BOOL finished) {
                    self.showViewController.isScale = NO;
                }];
            }
        }
    }
    else if (self.showViewController.isScale == YES) {
        //已经缩放的情况下

        //计算比例
        CGFloat scaleXY = zoomScale - moveX / maxMoveX * WNXZoomScaleRight;

        if (moveX <= 5) {

            CGAffineTransform transform = CGAffineTransformMakeScale(scaleXY, scaleXY);

            self.showViewController.navigationController.view.transform = CGAffineTransformTranslate(transform, (moveX + maxMoveX), 0);
        }
        //当手势停止的时候,判断X轴的移动距离,停靠
        if (pan.state == UIGestureRecognizerStateEnded) {
            //计算剩余停靠时间
            if (-moveX >= maxMoveX / 2) {
                CGFloat duration = 0.5 * (maxMoveX + moveX)/maxMoveX > 0 ? 0.5 * (maxMoveX + moveX)/maxMoveX : -(0.5 * (maxMoveX + moveX)/maxMoveX);
                if (duration <= 0.1) duration = 0.1;
                //直接停靠到停止的位置
                [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveLinear animations:^{

                    self.showViewController.navigationController.view.transform = CGAffineTransformIdentity;

                } completion:^(BOOL finished) {
                    //将状态改为已经缩放
                    self.showViewController.isScale = NO;
                    //手动点击按钮添加遮盖
                    [self.showViewController coverClick];
                }];

            } else {//X轴移动不够一半 回到原位,不是缩放状态

                [UIView animateWithDuration:0.2 animations:^{

                    CGAffineTransform tt = CGAffineTransformMakeScale(zoomScale, zoomScale);
                    self.showViewController.navigationController.view.transform = CGAffineTransformTranslate(tt, maxMoveX, 0);

                } completion:^(BOOL finished) {
                    self.showViewController.isScale = YES;
                }];
            }
        }
    }

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值