美文网首页iOS点点滴滴
侧滑效果实现思路

侧滑效果实现思路

作者: fmxccccc | 来源:发表于2017-02-22 22:59 被阅读122次

    一直想要研究下QQ的侧滑效果,最近也正好在做这方面的东西,便记录一下实现的思路,其实在网上也有很多第三方的开源侧滑框架这里推荐一下MMDrawerController.

    接下来开始今天的主题,先来介绍下我的大体思路:

    首先我的底部是一个容器viewController(关于容器controller的概念可以去看一看Objc中国的第一个专题中的这篇文章),在这个容器controller上面加载了一个MainViewConller以及一个menuView并且我的MainViewController是一个NavigationController的rootViewController,在手势滑动的时候在这个mainViewController上加了一个遮罩的UIControl.

        [self.view addSubview:self.menuView];
        
        _mainNav = [[UINavigationController alloc] initWithRootViewController:self.mainViewController];
        [self addChildViewController:_mainNav];
        _mainNav.view.frame = self.view.frame;
        [self.view addSubview:_mainNav.view];
        [_mainNav didMoveToParentViewController:self];
    
    

    然后在我的容器controller中添加了一个UIScreenEdgePanGestureRecognizer手势,这个手势只作用于屏幕的边缘,可以根据edges属性来设置手势的方向,这里我设置的是UIRectEdgeLeft.下面是手势中的方法

    // 手指在屏幕中位置
    CGFloat panLocationX = [pan locationInView:self.view].x;
    // 根据屏幕宽度算出比例
    CGFloat percentage = panLocationX / CGRectGetWidth(self.view.bounds);
    switch (pan.state)
    {
        case UIGestureRecognizerStateBegan:
        case UIGestureRecognizerStateChanged:
        {
            // 将比例传入方法中进行计算 
            [self viewUpdateTrasition:percentage];
        }
            break;
        case UIGestureRecognizerStateEnded:
        case UIGestureRecognizerStateCancelled:
        {
            if (percentage > 0.5)
            {
                [self viewShowMenu];
            }
            else
            {
                [self viewHideMenu];
            }
        }
            break;
        default:
            break;
    }
    

    主要的实现是在这个方法中viewUpdateTrasition:

    // 在这里添加遮罩的UIControl
    [_mainNav.view addSubview:self.maskControl];
    // 将传入的比例规整在0-1之间    
    CGFloat currentProgress = MAX(MIN(progress, 1), 0);
    // 这里使mainViewController的视图跟着手指的移动而移动
    _mainNav.view.transform = CGAffineTransformMakeTranslation((CGRectGetWidth(self.view.bounds) - 100) * currentProgress, 0);
    // 设置遮罩视图的透明度
    self.maskControl.alpha = currentProgress;
    // 计算出menuView的宽度
    CGFloat width = CGRectGetWidth(self.view.bounds) - 100;
    CGRect frame = self.menuView.bounds;
    frame.size.width = width;
    // 根据比例设置menuView的frame中的x值
    frame.origin.x = - (1 - currentProgress) * width * 0.4f;
    // 更新menuView的位置
    self.menuView.frame = frame;
    [self.menuView setNeedsLayout];
    [self.menuView layoutIfNeeded];
        
    // 条件判断,当比例为0的时候移除遮罩    
    if (progress == 0)
    {
        [self.maskControl removeFromSuperview];
    }
    

    这里需要重点说明几个地方:

    (CGRectGetWidth(self.view.bounds) - 100) * currentProgress这里减去100是为了使mainViewController的NavigationController移动到距离屏幕还剩100的位置的时候停止.

    CGFloat width = CGRectGetWidth(self.view.bounds) - 100这减去100是设置menu的宽度.

    frame.origin.x = - (1 - currentProgress) * width * 0.4f这里是通过比例计算出menuView所移动的位置,这里乘以0.4是为了造成一个时差的效果.

    下面是一个大致的效果:

    开.gif 关.gif

    相关文章

      网友评论

        本文标题:侧滑效果实现思路

        本文链接:https://www.haomeiwen.com/subject/mwkvwttx.html