实现“手机qq”侧滑菜单 -- 吴欧

基本数据采集

经过体验,手机QQ采用的应该是线性动画,即视图缩放比例等随手指在屏幕上滑动的距离以一次方程的形式变化。

提取基本数据,向右侧滑达到最大幅度时:

1、   右侧主视图左边界距离屏幕左边界的距离占屏幕宽度的比例为:78%

2、   右侧主视图的高度占屏幕高度的比例为:77%

分步实现:

1、实现主视图的缩放侧滑;

2、实现主视图与左视图的联动;

第一步,实现主视图的缩放侧滑

此前动手做时参考了一些类似的demo,发现许多是用手势UIPanGestureRecognizer来实现的,而本文将采用UITouch。并使用以下两个触摸触发事件:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

原理:

主视图mainVC的移动和缩放:

①. 主视图frmae的x坐标 = 主视图frmae的x坐标 + 手指滑动的x轴总偏移量偏移量;

#pragma mark - 手指在屏幕上移动
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{

    if ([event touchesForView:_mainVC.view]) {

        // 获取UITouch对象
        UITouch *touch = [touches anyObject];

        // 获取当前点
        CGPoint currentPoint = [touch locationInView:self.view];

        // 获取上一个点
        CGPoint prePoint = [touch previousLocationInView:self.view];

        // x轴偏移量:当手指移动一点的时候,x偏移多少
        CGFloat offsetX = currentPoint.x - prePoint.x;

        // 设置当前主视图的frame
        _mainVC.view.frame = [self getCurrentFrameWithOffsetX:offsetX];

        // 移动渐变效果 (明 - 暗)
        _blackCover.alpha = (1 - _mainVC.view.frame.origin.x / RTarget);

    }

    // 判断是拖拽 还是 点击tap
    _isDraging = YES;
}

②. 主视图的缩放比例 :

// 当手指偏移一点,根据X轴的偏移量算出当前主视图的frame
- (CGRect)getCurrentFrameWithOffsetX:(CGFloat)offsetX
{

    // 获取y轴偏移量,手指每移动一点,y轴偏移多少
    CGFloat offsetY = offsetX * _maxOffestHight / screenWidth;

    // 每次移动缩小比例
    CGFloat scale = (screenHeight - 2 * offsetY) / screenHeight;

#if 0
    if (offsetX < 0 && _mainVC.view.frame.origin.x <= 0)
    {

        // 往左边滑动
        scale = (screenH + 2 * offsetY) / screenH;

    }
#endif

    // 获取之前的frame ***************  限制成只能显示左视图!
    CGRect frame = _mainVC.view.frame;

    if ((frame.origin.x+offsetX) >=0 )
        frame.origin.x += offsetX;
    else
        frame.origin.x = 0;

    frame.size.height = frame.size.height *scale;
    frame.size.width = frame.size.width *scale;
    frame.origin.y = (screenHeight - frame.size.height) / 2.0;

    return frame;
}

/**  当手指偏移一点,根据X轴的偏移量算出当前主视图的frame **/

// 获取y轴偏移量,手指每移动一点,y轴偏移多少

CGFloat offsetY = offsetX * _maxOffestHight / screenWidth;

// 每次移动缩小比例

CGFloat scale = (screenHeight - 2 * offsetY) / screenHeight;

CGRect frame = _mainVC.view.frame;

… …

/** 主视图的位置变化 和 大小缩放 **/

frame.origin.x += offsetX;

frame.size.height = frame.size.height *scale;

frame.size.width = frame.size.width *scale;

frame.origin.y = (screenHeight - frame.size.height) / 2.0;

… …

第二步,实现主视图与左视图的联动

原理:

重点是找出线性关系,然后联动可以这样做 :
1、这是leftVC.view的缩放比例:

找出这两点 (0.77 ,0) (1 ,screenwidth
* 0.78),即(left.view的缩放比例, main.view.x坐标),可得线性关系:

CGFloat leftScale = ((1 - _minSclae)/(screenWidth * _boundScale))*_mainVC.view.frame.origin.x + _minSclae;
    leftCX = _mainVC.view.frame.origin.x >= screenWidth * _boundScale ? self.view.center.x : leftCX;

2、这是leftVC.view的移动:

找出这两点(self.view.center.x ,
screenwidth * 0.78) (center - 80 , 0),即(屏幕中心点x的坐标 ,main.view.or.x坐标),可得线性关系:

    CGFloat leftCX = ( _leftCenterFactor / (screenWidth * _boundScale) )*_mainVC.view.frame.origin.x + screenWidth/2 - _leftCenterFactor;

    leftScale = leftScale >= 1 ? 1 :leftScale;

3、最后移动和缩放:

_leftVC.view.center = CGPointMake(leftCX, self.view.center.y);

    _leftVC.view.transform = CGAffineTransformScale(CGAffineTransformIdentity, leftScale, leftScale);

完整代码:

/**
 * 开启左视图联动事件
 */
- (void)startedLeftViewLinkage
{
    // 执行左视图联动动画

    // (self.view.center.x , screenwidth * 0.78) (center - 80 , 0)  ==>  (中心点x的坐标 ,main.view.or.x坐标),线性关系
    CGFloat leftCX = ( _leftCenterFactor / (screenWidth * _boundScale) )*_mainVC.view.frame.origin.x + screenWidth/2 - _leftCenterFactor;
    leftCX = _mainVC.view.frame.origin.x >= screenWidth * _boundScale ? self.view.center.x : leftCX;

    // (0.77 , 0) (1 , screenwidth*0.78) ==》 (left.view的缩放比例, main.view.or.x坐标),线性关系
    CGFloat leftScale = ((1 - _minSclae)/(screenWidth * _boundScale))*_mainVC.view.frame.origin.x + _minSclae;
    leftScale = leftScale >= 1 ? 1 :leftScale;

    _leftVC.view.center = CGPointMake(leftCX, self.view.center.y);
    _leftVC.view.transform = CGAffineTransformScale(CGAffineTransformIdentity, leftScale, leftScale);
}

以上是对左视图和主视图的移动及缩放关系的解析,侧滑的关键就是找准视图之间的内在动态联系。按本文方法可达到高仿,实现的效果基本与手机QQ一样。

时间: 2024-11-02 01:30:28

实现“手机qq”侧滑菜单 -- 吴欧的相关文章

仿QQ侧滑菜单

仿QQ侧滑菜单 1.仿QQ侧滑(淡入淡出) 2.点击侧滑菜单相应地方响应事件 3.可以自定义侧滑菜单哦 下载地址:http://www.devstore.cn/code/info/846.html  运行截图:

Android自定义View之仿QQ侧滑菜单实现

最近,由于正在做的一个应用中要用到侧滑菜单,所以通过查资料看视频,学习了一下自定义View,实现一个类似于QQ的侧滑菜单,顺便还将其封装为自定义组件,可以实现类似QQ的侧滑菜单和抽屉式侧滑菜单两种菜单. 下面先放上效果图: 我们这里的侧滑菜单主要是利用HorizontalScrollView来实现的,基本的思路是,一个布局中左边是菜单布局,右边是内容布局,默认情况下,菜单布局隐藏,内容布局显示,当我们向右侧滑,就会将菜单拉出来,而将内容布局的一部分隐藏,如下图所示: 下面我们就一步步开始实现一个

android:自定义HorizontalScrollView实现qq侧滑菜单

今天看了鸿洋_大神在慕课网讲的qq5.0侧滑菜单.学了不少的知识,同时也佩服鸿洋_大神思路的清晰. 看了教程课下也自己实现了一下.代码几乎完全相同  别喷我啊..没办法 o(︶︿︶)o 唉 像素不好 没办法 找不到好的制作gif的软件. 我们暂且称侧滑左边界面的为menu,右边为content 首先是menu的布局 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:androi

Swift实战-小QQ(第2章):QQ侧滑菜单

QQ侧滑实现架构:需要建立以下几个ViewController:1.XQBaseViewController 2.LeftViewController3.RightViewController4.ContentViewController(中间显示的主要内容) 5.SliderViewController(用于控制侧滑动画,控制左右侧栏的显示和隐藏) 本章未完.待续... 谢谢关注.

鹅厂系列一 : 仿QQ侧滑菜单

--不会的东西你不尝试的去做,你永远都不会做 好了,跟随潮流,还是先看下效果,不然可能都没人想看下去了(不会看到效果后不想看了吧O(∩_∩)O~) 额,图片资源来自QQ_374.APK,里面四五千个图片,找这几个没把我累死,当然感谢QQ的资源,额,.先来看看初始布局,我不知道腾讯是怎么布局的,我自己为了做的像他们一点,我的布局暂时是像下面这样的,到了自定义控件的时候,还会进行重新测量和布局. 嗯,就是让左面板在主面板的下面,所以我们自定义的控件SlideLayout继承FrameLayout.一

ViewDragHelper的妙用二 --QQ侧滑菜单的实现

好了,还是老规矩,先给出效果图,这里就绘制了一个简单框架,各位看官可以任意添加自己的东西. 下面我来解释一下怎么使用我们的ViewDragHelper来实现这个效果 先给出我们的布局 <?xml version="1.0" encoding="UTF-8"?> <com.jeason.qqmenudemo.widget.SideslipLayout xmlns:android="http://schemas.android.com/apk

css3实现手机qq空间菜单按钮

工作之余写的一个类似于QQzone的菜单效果 先上截图: 图一为点击按钮前界面: 图二为点击按钮后的界面 下面上代码: <!--css部分--> <style type="text/css"> @font-face { font-family:'Raphaelicons'; src:url(font/raphaelicons-webfont.svg) format('svg'),url(font/raphaelicons-webfont.woff) format

android:QQ多种侧滑菜单的实现

在这篇文章中写了 自定义HorizontalScrollView实现qq侧滑菜单 然而这个菜单效果只是普通的侧拉效果 我们还可以实现抽屉式侧滑菜单 就像这样 第一种效果 第二种效果 第三种效果 第四种效果 其它代码都和上篇文章相同,只是在MyHorizontalScrollView.class重写onScrollChanged这个方法 第一种的侧滑效果代码很简单 @Override protected void onScrollChanged(int l, int t, int oldl, in

自定义侧滑菜单

类似于QQ侧滑菜单的效果,这个最重要的就是改变摆放方式,从而达到自己想要的效果,首先先弄明白onLayout方法里的参数 这个自定义里最主要的就是通过touch事件来移动显示的范围,移动viewgroup主要有几个方法,onLayout offsetTopAndBottom(offset)和offsetLeftAndRight(offset); scrollTo和scrollBy方法; 注意:滚动的并不是viewgroup内容本身,而是它的矩形边框 它是瞬间移动, 这里我们用的是scrollTo