之前的那文章简单实现了菜单侧拉功能,但是做不到像QQ那样导航条和tabBar一起移动。。。之后在网上找资料,有了思路,就自个写了个demo试试水。

先创建QHLMainController控制器,并把它设置成app的根控制器。

在QHLMainController控制器中,懒加载添加一个tableView,并对tableView设置相对应的属性以及frame(frame的x设置为一个负值)!!添加一个tabBar控制器,并

为tabBar控制器添加4个子控制器(分别为first,two,three,four)!!!并对tabBar控制器的view的frame 添加一个KVO监听,监听当tabBar控制器 的view的frame的改

变,并执行相对应的代码。在tabBar控制器的第一个子控制器first控制器中,添加拖动手势,当拖动时候,根据拖动的偏移量来改变自身tabBar控制器的view的frame的

值。当偏移量达到最大的时候  给view添加点击手势,当点击时候,使view的frame变回初始值!!当frame变回初值的时候,移除点击手势。

在QHLMainController控制器中

 - (void)viewDidLoad {
[super viewDidLoad]; //添加懒加载的tableView
[self.view addSubview:self.tableView]; //设置主界面
[self setUpMainUI];
} /**
* 设置主界面
*/ - (void)setUpMainUI {
//创建tabBar控制器并添加到根控制器中
QHLTabBarController *tabVc = [[QHLTabBarController alloc] init];
self.tabVc = tabVc;
[self addChildViewController:tabVc];
[self.view addSubview:tabVc.view];
//对tabBar控制器view的frame属性添加一个监听
[tabVc.view addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil]; }
/**
* tabBar控制器view的frame属性的监听事件
*/ #define QHLViewControllerMaxOffsetX 250
#define QHLLeftViewOriginX -50 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
//计算偏移量
CGFloat offsetX =QHLLeftViewOriginX - QHLLeftViewOriginX * (self.tabVc.view.frame.origin.x) / QHLViewControllerMaxOffsetX;
//改变tableView的frame
CGRect frame = self.tableView.frame;
frame.origin.x = offsetX;
self.tableView.frame = frame;
}

tableView的懒加载和dataSource方法就不放上来了。

在tabBar控制器的子控制器first控制器中,先添加枚举型的结构体

 typedef NS_ENUM(NSInteger, QHLViewControllerState) {
QHLViewControllerStateClosed = ,
QHLViewControllerStateOpening,
QHLViewControllerStateOpened,
QHLViewControllerStateClosing
};

首先在viewWillAppear:中添加拖动手势,并添加到当前view中,然后在viewWillDisappear:方法中把拖动手势移除掉。

在viewDidLoad方法中:

1.把自身的state状态设置成QHLViewControllerStateClosed

2.添加navigationItem的leftBarButtonItem:封装一个UIButton,设置相关的属性设置、一个背景色以及添加一个点击方法

点击方法如下:

 /**
* leftItem的点击事件
*/
- (void)leftItemDidClick:(UIButton *)leftItem {
if (self.state == QHLViewControllerStateClosed) {
[self animatingOpen];
} else {
[self animatingClose];
}
}

拖动手势事件方法实现:

 /**
* 拖动手势的实现方法
*/
- (void)panGestureRecognized:(UIPanGestureRecognizer *)panGestureRecognizer {
CGPoint location = [panGestureRecognizer translationInView:self.view]; //位置
CGRect frame = self.tabBarController.view.frame;
//获取当前拖动手势的状态
UIGestureRecognizerState state = panGestureRecognizer.state; switch (state) {
//拖动手势开始时候
case UIGestureRecognizerStateBegan:
self.beginLocation = location; //开始位置
if (self.state == QHLViewControllerStateClosed) { [self willOpen];
} else { [self willClose];
}
break;
//拖动手势进行中
case UIGestureRecognizerStateChanged:
{
CGFloat offsetX = ; //偏移量X //根据自身的state来设置不同的offsetX
if (self.state == QHLViewControllerStateOpening) { //正在打开
offsetX = location.x - self.beginLocation.x;
} else { //正在关闭
offsetX = QHLViewControllerMaxOffsetX - (self.beginLocation.x - location.x);
} if (offsetX >= QHLViewControllerMaxOffsetX) { //偏移量超过最大偏移值时
frame.origin.x = QHLViewControllerMaxOffsetX;
} else if (offsetX <= ) { //只有在关闭时候才会出现偏移量小于0的情况,而此种情况下,偏移量小于0,会使自身的x值小于0
frame.origin.x = ;
} else { //正在打开或者正在关闭
frame.origin.x = offsetX;
} //计算透明度
CGFloat alpha = - offsetX / QHLViewControllerMaxOffsetX;
self.leftItem.alpha = alpha; //设置导航条左侧item的透明度
self.tabBarController.view.frame = frame;
break;
}
//拖动手势结束时
case UIGestureRecognizerStateEnded:
if (self.state == QHLViewControllerStateOpening) { //正在打开
if (frame.origin.x >= QHLViewControllerMaxOffsetX / ) { //判断此时的偏移量
[self animatingOpen];
} else {
[self animatingClose];
} } else { //正在关闭
if (frame.origin.x >= QHLViewControllerMaxOffsetX / ) { //判断此时的偏移量
[self animatingOpen];
} else {
[self animatingClose];
}
}
break; default:
break;
}
}

点击手势事件方法实现:

 - (void)tapGestureRecognized:(UITapGestureRecognizer *)tapGestureRecognizer {
//点击事件 自动缩回侧拉界面
[self animatingClose];
}

当tabBar控制器的view在偏移的时候,会调用下面的几个方法:

 /**
* willOpen
*/
- (void)willOpen {
self.state = QHLViewControllerStateOpening;
} /**
* opened
*/
- (void)opened {
self.state = QHLViewControllerStateOpened; //设置点击手势
self.tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureRecognized:)];
[self.view addGestureRecognizer:self.tapGestureRecognizer];
} /**
* willClose
*/
- (void)willClose {
self.state = QHLViewControllerStateClosing;
} /**
* closed
*/
- (void)closed {
self.state = QHLViewControllerStateClosed;
[self.view removeGestureRecognizer:self.tapGestureRecognizer];
} /**
* 以动画形式打开
*/
- (void)animatingOpen {
[UIView animateWithDuration:0.5 delay: usingSpringWithDamping:1.0 initialSpringVelocity:0.7 options:UIViewAnimationOptionCurveLinear animations:^{
self.tabBarController.view.frame = CGRectMake(QHLViewControllerMaxOffsetX, , self.view.frame.size.width, self.view.frame.size.height); self.leftItem.alpha = ;
} completion:^(BOOL finished) {
[self opened];//改变自身的state状态以及移除点击手势
}];
} /**
* 以动画形式关闭
*/
- (void)animatingClose {
[UIView animateWithDuration:0.5 delay: usingSpringWithDamping:1.0 initialSpringVelocity:0.7 options:UIViewAnimationOptionCurveLinear animations:^{
self.tabBarController.view.frame = CGRectMake(, , self.view.frame.size.width, self.view.frame.size.height); self.leftItem.alpha = ;
} completion:^(BOOL finished) {
[self closed]; //改变自身的state状态以及添加点击手势
}];
}

模拟器测试了下,基本实现了和QQ左上角的导航条item点击触发的相类似的功能~。~

如果路过的大神有更好的实现方法求指导下!!!!

类似QQ侧滑菜单功能实现的更多相关文章

  1. 再造 “手机QQ” 侧滑菜单(三)——视图联动

    代码示例:https://github.com/johnlui/SwiftSideslipLikeQQ 本 文中,我们将一起使用 UINavigationController 来管理主视图,并实现点击 ...

  2. 自定义控件?试试300行代码实现QQ侧滑菜单

    Android自定义控件并没有什么捷径可走,需要不断得模仿练习才能出师.这其中进行模仿练习的demo的选择是至关重要的,最优选择莫过于官方的控件了,但是官方控件动辄就是几千行代码往往可能容易让人望而却 ...

  3. iOS仿QQ侧滑菜单、登录按钮动画、仿斗鱼直播APP、城市选择器、自动布局等源码

    iOS精选源码 QQ侧滑菜单,右滑菜单,QQ展开菜单,QQ好友分组 登录按钮 3分钟快捷创建高性能轮播图 ScrollView嵌套ScrolloView(UITableView .UICollecti ...

  4. 再造 “手机QQ” 侧滑菜单(一)——实现侧滑效果

    本系列文章中,我们将尝试再造手机QQ的侧滑菜单,力争最大限度接近手Q的实际效果,并使用 Auto Layout 仿造左侧菜单,实现和主视图的联动. 代码示例:https://github.com/jo ...

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

    QQ侧滑实现架构:需要建立以下几个ViewController:1.XQBaseViewController 2.LeftViewController3.RightViewController4.Co ...

  6. 仿QQ侧滑菜单<大自然的搬运工-代码不是我的>

    1.记录下效果图 2.二个工具类 package myapplication.com.myapplicationfortest.utils; import android.util.Log; /** ...

  7. 再造 “手机QQ” 侧滑菜单(二)——高仿左视图

    代码示例:https://github.com/johnlui/SwiftSideslipLikeQQ 本篇文章中,我们将一起使用 Auto Layout 高仿手Q的左侧视图,力争达成从布局到动画的全 ...

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

    基本数据采集 经过体验,手机QQ采用的应该是线性动画,即视图缩放比例等随手指在屏幕上滑动的距离以一次方程的形式变化. 提取基本数据,向右侧滑达到最大幅度时: 1.   右侧主视图左边界距离屏幕左边界的 ...

  9. 今日推荐(三)AndroidResideMenu类似QQ侧滑效果

    效果图: DEMO 本代码即是DEMO,您可以下载后选择您喜欢的IDE运行.SDK版本建议使用4.0以上 Version Migration 从 v1.0, v1.1, v1.2, v1.3 升级到  ...

随机推荐

  1. kmp代码实现

    /* kmp彻底理解 next 数组 :用来指导S[i]串 T[j]串 对应字符失配 指导 i 不回溯,即j应该走多少个位置 next[j]:j位置前一个元素 需要 计算某个字符对应的next值,就是 ...

  2. 关于局域网内IIS部署网站,本机可访问,而网内其他用户无法访问问题的解决方法

    在Window7操作系统中安装配置好IIS后,在本地IIS上部署网站程序没有问题,但是局域网等远程用户不能正常访问网站程序,提示“Internet Explorer 无法显示该网页”. 问题解决思路如 ...

  3. OpenGL ES 2.0 光照

    基本的光照 光照分成了3种组成元素(3个通道):环境光.散射光以及镜面光. 材质的反射系数实际指的就是物体被照射处的颜色,散射光强度指的是散射光中的RGB(红.绿.蓝)3个色彩通道的强度. 环境光 指 ...

  4. html label 标签的 for 属性

    如果您在 label 元素内点击文本,就会触发此控件.就是说,当用户选择该标签时,浏览器就会自动将焦点转到和标签相关的表单控件上. 有两种使用方法: 方法1 使用for属性 <label for ...

  5. WCF+AJAX最佳实践

    本文是基于Frank Xu的一个webcast上的串并总结,图片等都截至视频,谨致谢. 路线图 什么是WCF Windows Communication Foundation是MS为构建面向服务的应用 ...

  6. java生成UUID通用唯一识别码 (Universally Unique Identifier)

    转自:http://blog.csdn.net/carefree31441/article/details/3998553 UUID含义是通用唯一识别码 (Universally Unique Ide ...

  7. JS 没有块级作用域

    在函数(方法)中声明的所有变量,他们在整个函数中都有定义 var scope="abc"; function f() { alert(scope);  //显示undefine v ...

  8. linux配置备忘

    ubuntu英文系统环境下,emacs输入中文设置:(http://www.cnblogs.com/pylemon/archive/2012/01/05/2312682.html) ~/.profil ...

  9. 观《Terminal》之感

    读书笔记系列链接地址http://www.cnblogs.com/shoufengwei/p/5714661.html.        经人推荐,用了几天时间欣赏了这部斯皮尔伯格导演的电影<Te ...

  10. 根据样式获取被选中的checkbox

    <ul id="> </div> </li></ul> $("#btn_CheckManagerCompletionCreateAt ...