iOS仿今日头条滑动导航
之前写了篇博客网易首页导航封装类、网易首页导航封装类优化,今天在前两个的基础上仿下今日头条。
1.网易首页导航封装类中主要解决了上面导航的ScrollView和下面的页面的ScrollView联动的问题,以及上面导航栏的偏移量。
2.网易首页导航封装类优化中主要解决iOS7以上滑动返回功能中UIScreenEdgePanGestureRecognizer与ScrollView的滑动的手势冲突问题。
今天仿今日头条滑动导航和网易首页导航封装类优化相似,这个也是解决手势冲突,UIPanGestureRecognizer与ScrollView的手势冲突。

一、ViewController的层次
用上面的图来介绍,左侧的个人页面ViewController上面通过addChildViewController添加了一个以MainViewController为RootViewController的
UINavigationController,通过addSubview将UINavigationController的View添加到个人页面ViewController的View上。
二、仿今日头条滑动导航主要有4个问题:
1.UIPanGestureRecognizer与ScrollView的手势冲突
为了达到拖动滑动的效果,需要给MainViewController添加一个UIPanGestureRecognizer,由于底部是ScrollView和TableView组成的,所以会使UIPanGestureRecognizer与底部的冲突,和网易首页导航封装类优化类似需要在
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer中根据gestureRecognizer返回YES来使ScrolView和UIPanGestureRecognizer都识别。
2.UIPanGestureRecognizer滑动结束的位置不正确
用UIPanGestureRecognizer滑动根据偏移量来改变UINavigationController的View的位置,在今日头条中滑动结束时UINavigationController的View要么在原位要么在右侧,不会停在中间,这个问题让我想起了之前做的果冻效果,手势有状态state,根据手势的状态来改变UINavigationController的View的位置,特别是在手势结束时。
3.由于1使ScrolView和UIPanGestureRecognizer都识别,导致返回时ScrolView也会滑动
让底部的ScrolView能滑动的时间应该是UINavigationController的View在初始位置frame的x为0,所以在它的frame的x>0时,底部的bottomScrollView scrollEnabled=NO。
4.页面拖到右边时点击右边页面可以滑到初始位置
首先时点击滑到初始页面则需要给UINavigationController的View添加轻点手势,添加后就会与tableView的手势冲突,所以有出现了一个新的bug,解决这个bug还比较好解决,因为bottomScrollView的ScrollView只有Pan、pich手势,tap手势没有,所以只要设置tap轻点手势的状态就能解决. 在UINavigationController的View的frame的x>0时,tap手势的enable=NO,==0时为Yes即可(上周未将轻点加上,这周算是补上了,下面具体实现代码我就不改了)。
三、 主要实现代码(导航的代码就不贴了,只贴主要的)
1.声明一个拖动手势
@property(nonatomic,strong) UIPanGestureRecognizer *panGestureRecognizer;
2.为MainViewController添加手势
_panGestureRecognizer=[[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panGesture:)];
_panGestureRecognizer.delegate=self;
[self.navigationController.view addGestureRecognizer:_panGestureRecognizer];
3.手势识别的方法
//平移
-(void)panGesture:(UIPanGestureRecognizer*)pan
{
//在View中的位置
// CGPoint point=[pan locationInView:self.navigationController.view];
//在View中的移动量 以手指按下的为原点
CGPoint point1=[pan translationInView:self.navigationController.view];
if (pan.state==UIGestureRecognizerStateChanged&&pan==_panGestureRecognizer) {
&&self.navigationController.view.frame.origin.x<self.navigationController.view.frame.size.width-) {
//下面if主要是解决tableView滑动会引起navigationController.View也滑动的bug
&&self.navigationController.view.frame.origin.x==) {
return;
}
?self.navigationController.view.frame.size.width-:self.navigationController.view.frame.origin.x+point1.x;
self.navigationController.view.frame=CGRectMake(x, self.navigationController.view.frame.origin.y, self.navigationController.view.frame.size.width, self.navigationController.view.frame.size.height);
NSLog(@"%@",NSStringFromCGRect(self.navigationController.view.frame));
}
)
{
NSLog(@"aaa %f",self.navigationController.view.frame.origin.x);
?:self.navigationController.view.frame.origin.x+point1.x;
self.navigationController.view.frame=CGRectMake(x, self.navigationController.view.frame.origin.y, self.navigationController.view.frame.size.width, self.navigationController.view.frame.size.height);
}
}
else if(pan.state==UIGestureRecognizerStateEnded)
{
) {
[UIView animateWithDuration:0.2 animations:^{
self.navigationController.view.frame=CGRectMake(self.navigationController.view.frame.size.width-, , self.navigationController.view.frame.size.width, self.navigationController.view.frame.size.height);
} completion:^(BOOL finished) {
self.bottomScrollView.scrollEnabled=YES;
}];
}
else
{
[UIView animateWithDuration:0.2 animations:^{
self.navigationController.view.frame=CGRectMake(, , self.navigationController.view.frame.size.width, self.navigationController.view.frame.size.height);
} completion:^(BOOL finished) {
self.bottomScrollView.scrollEnabled=YES;
}];
}
}
//偏移量是增加的应该设为0
[pan setTranslation:CGPointZero inView:self.navigationController.view];
}
4.手势冲突解决
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
if (self.bottomScrollView.contentOffset.x<=0.0&&gestureRecognizer==_panGestureRecognizer) {
) {
self.bottomScrollView.scrollEnabled=NO;
}
else
{
self.bottomScrollView.scrollEnabled=YES;
}
return YES;
}
return NO;
}
四、效果图


iOS仿今日头条滑动导航的更多相关文章
- Android之仿今日头条顶部导航栏效果
随着时间的推移现在的软件要求显示的内容越来越多,所以要在小的屏幕上能够更好的显示更多的内容,首先我们会想到底部菜单栏,但是有时候像今日头条新闻客户端要显示的内容太多,而且又想在主界面全部显示出来,所以 ...
- 自适应 Tab 宽度可以滑动文字逐渐变色的 TabLayout(仿今日头条顶部导航)
TabLayout相信大家都用过,2015年Google大会上发布了新的Android Support Design库里面包含了很多新的控件,其中就包含TabLayout,它可以配合ViewPager ...
- vue 仿今日头条
vue 仿今日头条 为了增加移动端项目的经验,近一周通过 vue 仿写今日头条,以下就项目实现过程中遇到的问题以及解决方法给出总结,有什么不正确的地方,恳请大家批评指正^ _ ^!,代码仓库地址为 g ...
- vue2.0仿今日头条开源项目
vue-toutiao 这是用 vue.js 2.0 高仿 今日头条 的移动端项目,结合了原生app的部分功能以及网页版. 前言 本人是 今日头条 的重度用户,在学习vue.js过程中,在GitHub ...
- [Android] Android 手机下 仿 今日头条 新闻客户端
利用一个月的时间,自学了 Android 开发 ,为了检验学习成果,特意 开发了这个 仿 今日头条 新闻客户端 AppNews 包括图文新闻+视频新闻+图片新闻 预览演示如下: 功能说明: 1)底部 ...
- Android 仿今日头条频道管理(下)(GridView之间Item的移动和拖拽)
前言 上篇博客我们说到了今日头条频道管理的操作交互体验,我也介绍了2个GridView之间Item的相互移动.详情请參考:Android 仿今日头条频道管理(上)(GridView之间Item的移动和 ...
- android仿今日头条App、多种漂亮加载效果、选择器汇总、记事本App、Kotlin开发等源码
Android精选源码 android漂亮的加载效果 android各种 选择器 汇总源码 Android仿bilibili搜索框效果 Android记事本app.分类,涂鸦.添加图片或者其他附件 仿 ...
- 仿今日头条最强顶部导航指示器,支持6种模式-b
项目中经常会用到类似今日头条中顶部的导航指示器,我也经常用一个类似的库PagerSlidingTabStrip,但是有时并不能小伙伴们的所有需求,所以我在这个类的基础上就所有能用到的情况做了一个简单的 ...
- Android 仿今日头条频道管理(上)(GridView之间Item的移动和拖拽)
前言 常常逛今日头条.发现它的频道管理功能做的特别赞.交互体验很好.如图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fo ...
随机推荐
- C# 使用 COALESCE 表达式简化 Null 检查
下面这个判断 null 的语句: a == null ? b: a 可以用 COALESCE 表达式,简化成: a ?? b
- 浅析C#中的IEquatable<T>接口
1.引言 首先我们先来看看IEquatable<T>接口的出现解决了什么问题. 我们知道,Object基类的Equals方法存在两个明显的问题.一是缺乏类型安全性,二是对于值类型而言需要装 ...
- .NET中的异常处理机制(一)
1.异常处理的总体指导思想 学习C#中的异常处理机制,大概要了解以下几点: 首先,我们需要知道的事所有具体异常都是继承自System.Exception基类的. 其次,要熟悉FCL类库内置好的一些异常 ...
- MySQL多线程备份工具mydumper 之 RDS外部实例迁移平台
此文已由作者温正湖授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 1.Format_description_event问题: BINLOG ' kTXkUxMKAAAALQA ...
- django系列6--Ajax04 请求设置(设置csrf_token)
Ajax请求设置csrf_token 官方文档 csrf_token: https://docs.djangoproject.com/en/1.11/ref/csrf/ CSRF 跨站请求攻击,简单地 ...
- 【ocp-12c】最新Oracle OCP-071考试题库(43题)
43.(9-2)choose three Which three tasks can be performed by DDL statements? A) preventing data retrie ...
- Vulnhub Billu_b0x
1.信息收集 1.1.获取IP地址: map scan report for 192.168.118.137 Host is up (0.00017s latency). Not shown: 998 ...
- DC010的精华分享【首发速看】
世界黑客大会[DC010] 是全球安全圈最神秘.最前沿的黑客大派对 而作为中国首个受DEFCON授权支持成立的 地区性 信息 安全 技术交流平台 DEFCONGROUP 010(DC010) 在国内 ...
- 记一次优化ansible inventory的小例子
起因: 阿里云新扩容一批机器,要对上面的flume配置做修改 之前的inventory是这样子的 [user@vip10-ali-tj-console host_vars]$ sdiff vip10- ...
- IntelliJ IDEA中可以用Tab键跳出括号和引号吗?
在 Settings->Editor->General->Smart Keys 中勾选 Jump outside closing bracket/quote with Tab 即可.