美文网首页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