之前的那文章简单实现了菜单侧拉功能,但是做不到像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点击触发的相类似的功能~。~

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

最新文章

  1. piap.windows io 监测attilax总结
  2. MFC学习-第4课 消息机制和MFC作图
  3. Android实例-调用GOOGLE的TTS实现文字转语音(XE7+小米2)(无图)
  4. VMware vSphere服务器虚拟化实验十一高可用性之三Fault Tolerance
  5. 第2章Zabbix基础进阶
  6. js中的事件缓存机制
  7. Java利用Apache POI将数据库数据导出为excel
  8. Unity用Excel.dll简单读取Excel内容
  9. Golang知识图谱
  10. C高级第二次作业
  11. Redis集群master选举时长测试
  12. SQL 将一列多行数据合并为一行
  13. maven打包时跳过单元测试
  14. 如何使用Git上传项目代码到github
  15. How to solve the problem : &amp;quot;You have been logged on with a temporary profile&amp;quot;
  16. java.lang.System.arraycopy() 与java.util.Arrays.copyOf()的区别
  17. ZH奶酪:在博客中添加Latex公式
  18. Single Number 数组中除了某个元素出现一次,其他都出现两次,找出这个元素
  19. 2017-2018 ACM-ICPC, Asia Daejeon Regional Contest
  20. 关于RTKLIB资料整理和学习

热门文章

  1. (四)CodeMirror - API
  2. android控制之 adb shell (已完成,不定期增加内容)
  3. 常见的DoDataExchange什么意思
  4. vs UNICODE 零散的笔记
  5. WordPress插件制作教程(五): 创建新的数据表
  6. C语言实现的OOP
  7. C++之------进制学习
  8. 对163k地方门户网站系统QQ互联功能修改
  9. VC6-Win7下VC++6.0打开多个工程的设置
  10. 董事长、总裁与CEO的区别与实质