当内容及分类较多时,往往采用顶部标签式导航栏,例如网易新闻客户端的顶部分类导航,最近刚好有这样的应用场景,参考网络上一些demo,实现了这种导航效果,记录一些要点。

效果图(由于视频转GIF掉帧,滑动和下拉动画显得比较生硬,刚发现quickTime可以直接录制手机视频,推荐一下,很方便)

1.顶部标签式导航栏

(1)实现思路

其实就是在上下两个UIScrollView上做文章,实现联动选择切换的效果。

①顶部标签导航栏topCategoryListScrollView加载显示分类数据,下方contentScrollView显示分类对应的内容,选择顶部标签后,内容视图contentScrollView切换到对应视图。同样,滑动下方内容视图,标签栏滑动到指定分类并居中显示,若分类初始位置在导航栏最左侧或最右侧,则不用滑动到中间位置。以免两侧留出一段空白。

②顶部导航栏可以用label或button来代表分类,这里用的是label,添加了一个tap手势响应交互事件,将分类抽取为一个model,包含分类名称、对应内容视图特有的id或url及分类名称长度(分类下方的下划线长度随名称长度变化)等属性,根据分类的多少,决定下方内容视图的contentSize,再将分类顺序与内容顺序对应起来,在交互逻辑中实现联动切换。

③点击右侧按钮,弹出下拉菜单,也可切换分类。

(2)iOS7上Autolayout的问题

由于iOS7的Autolayout与iOS8、9的差异,在iOS7上UIScrollView的contentsize及一些使用Autolayout的UIView动画效果不好处理,所以这里使用setFrame的方式来实现两个顶部导航栏及下拉菜单的UI效果。

(3)顶部导航栏

遍历分类数据,往顶部导航栏添加label。需要注意以下几点:

①设置label的tag,与分类数据的index对应,方便后续根据标识进行切换选择;

②label的userInteractionEnabled默认为NO,需要设置一下,方便响应tap点击操作;

③分类名称长度是动态的,如果超出默认长度则根据实际长度显示,包括label的长度及label底部下划线长度,所以分类数据对应的model里需要有一个长度属性,用来记录此长度,方便后续显示,而不用实时去计算长度。

分类名称底部的下划线随着分类label走,默认选中第一个label,所以下划线默认也是停留在第一个,并且根据分类数量设置好顶部导航栏的contentSize。

(4)内容视图

同样根据分类数量设置好内容视图的contentSize

(5)两个scrollView之间的交互逻辑

两个scrollView之间的联动需要注意单向传递,避免发生重复滑动。这里的滑动选择操作就三种情况:

①选择某个分类标签,导航栏滑动到指定位置,内容视图滑动到指定位置;

②滑动内容视图,导航栏也切换滑动到对应分类标签位置;

③在下拉菜单中选择了某个分类,导航栏和内容视图滑动到对应位置,实际与①一样。

这里先说第一种情况,点击导航栏的分类标签,则block回调到controller里

先让contentScrollView滑动到指定位置,再通知topCategoryListScrollView滑动。

这里需要说明一下,scrollViewDidEndScrollingAnimation原本是内容视图滑动结束后调用,用来通知导航栏滑动到对应分类标签。scrollViewDidEndDecelerating是处理手指在屏幕上滑动内容视图结束后调用,也是通知导航栏滑动到对应分类标签。但是为了让滑动时分类标签切换显示效果更更连贯,在scrollViewDidScroll里进行了处理,当滑出一定距离,新的index与当前index不一致时就通知导航栏切换分类标签,实际上scrollViewDidEndScrollingAnimation和scrollViewDidEndDecelerating这时已经可以去掉了。

类似的,第二种情况,滑动内容视图,导航栏切换滑动到对应分类标签位置,实际就是在ScrollViewDidScroll中进行判断处理的。

对于第三种情况,下拉菜单中选择分类,实际过程与第一种情况一样。

需要注意的是切换分类时,需要记录更新当前分类的值,弹出下拉菜单的时候,才能标识高亮当前分类。

导航栏滑动的时候,需要针对分类标签的具体位置,决定是否滑动,以及滑动距离,并根据分类名称长度更新下划线的长度

但是这里还忽略了一种情况,当分类标签显示不足一屏时,offsetMax为负值,点击某个分类,会将所有分类整体往右移动,非常怪异,这种情况下,点击分类就不需要滚动了。

2.下拉分类菜单

(1)使用场景及方式

下拉逐渐展开分类菜单,选择某一个分类,导航栏和内容视图切换到对应分类及内容,展开状态时,点击按钮或者背景阴影区域逐渐收起菜单。

(2)UI元素分解

一个放在导航栏旁边的按钮dropDownButton,一个titleView(其实titleView放在下拉菜单里更合适,这样就不需要单独处理它),以及下拉分类菜单dropDownCategoryListView,里面包含一个collectionView展示分类数据。dropDownButton控制titleView及dropDownCategoryListView的显示,dropDownCategoryListView背景色设置一定透明度做背景。接下来总结一下几个关键点。

(3)collectionView高度控制及分隔线效果

这里每一行显示三个分类数据,分类数量及cell高度确定后即可确定collectionView的高度,即先确定纵向有几行分类数据,行数 x cell高度就是collectionView 高度。

这里还需要注意一点,默认设置collectionView是不可滑动的,但是需要判断一下分类显示的高度,超出可视范围时,需要允许滑动。

对于分类cell的分隔线效果,可能最容易想到的就是cell之间留出间隙,collectionView背景色设置一下就行了,但是这里有两个问题,首先是三等分cell加上留出的间隙,间隙的宽度会带有小数,显示出来的效果粗细不均,并且这里cell与collectionview背景色都为白色,留出空隙也无法形成分隔线的视觉效果,所以只能在cell内部处理,底部和右侧加分隔线,根据cell所处位置控制分隔线显示与否。

(4)点击collectionView的事件处理

dropDownCategoryListView 添加了tap手势,点击view则通知controller收起移除下拉分类菜单 ,collectionView作为一部分,点击collectionView也会通知controller收起移除下拉分类菜单,显然不符合要求,解决办法是将手势的cancelsTouchesInView属性设为NO,即将touch事件也传递到collectionView上,didSelect选中分类后继续处理即可。

(5)交互效果处理

下拉菜单的展开和收起渐变效果用UIView的animation即可,需要注意的是收起动画效果,需要先去掉阴影,然后收起下拉菜单,这里的阴影其实就是dropDownCategoryListView设置了一定透明度的背景色,所以先将背景色设成clearColor再收起菜单即可。

3.参考

(1)http://code.cocoachina.com/view/128556

(2)https://github.com/dsxNiubility/SXNews

iOS开发笔记13:顶部标签式导航栏及下拉分类菜单的更多相关文章

  1. CSS 笔记——导航栏、下拉菜单、提示工具

    8. 导航栏.下拉菜单.提示工具 (1)导航栏 垂直导航栏 <!DOCTYPE html> <html lang="en"> <head> &l ...

  2. python测试开发django-41.crispy-forms设计标签式导航菜单(TabHolder)

    前言 xadmin的详情页面主要是用form_layout布局,学会了完全可以不用写html代码,也能做出很好看的页面. xadmin的html页面是用的Bootstrap3框架设计的,layout布 ...

  3. iOS开发-仿大众点评iPad侧边导航栏

    昨天其实已经写了一篇侧边栏的文章,不过感觉还不是很清晰,这篇文章算是补充吧,iPad上看了大众点评的侧边栏,基本上百分之九十类似,具体效果可参考下图: 对比昨天主要做了两个修改,一个是图片和文字的显示 ...

  4. Bootstrap 学习笔记 项目实战 响应式导航栏

    导航代码HTML: <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset=&q ...

  5. HTML+CSS实现导航栏二级下拉菜单完整代码

    工具是vs code 代码如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset ...

  6. iOS开发-- 通过runtime kvc 移除导航栏下方的阴影效果线条

    网上查了很多, 都是重新绘制, 感觉有点蠢, 恰巧工作有会闲, 就简单的通过runtime遍历了下属性找寻了下私有类和方法, 这里直接贴方法, 找寻过程也发出来, 能看懂的直接就能看懂, 看不太明白的 ...

  7. CSS学习笔记六:写原生导航栏

    因为刚开始学习CSS时,只了解了一些基本样式,然后就跑去学习bootstrap.bootstrap是个不错的东西,挺好玩,起码让你写界面写的轻轻松松,几行引入代码,再来个复制粘贴就解决了,而且boot ...

  8. iOS开发笔记7:Text、UI交互细节、两个动画效果等

    Text主要总结UILabel.UITextField.UITextView.UIMenuController以及UIWebView/WKWebView相关的一些问题. UI细节主要总结界面交互开发中 ...

  9. 菜鸟手下的iOS开发笔记(swift)

    在阳春4月的一天晨会上,有一个老板和蔼的对他的一个菜鸟手下说:“你既然会Android,那你能不能开发iOS?” 不是说好的要外包的吗?内心跌宕,但是表面淡定的菜鸟手下弱弱的回道:“可以试试”. 第二 ...

随机推荐

  1. 如何编写Angular指令

    [20140917]Angular:如何编写一个指令 *:first-child { margin-top: 0 !important; } body>*:last-child { margin ...

  2. [python]pythonic的字典常用操作

    注意:dct代表字典,key代表键值 1.判断字典中某个键是否存在 实现 dct.has_key(key) #False 更Pythonic方法 key in dct #False 2.获取字典中的值 ...

  3. CART(分类回归树)原理和实现

    前面我们了解了决策树和adaboost的决策树墩的原理和实现,在adaboost我们看到,用简单的决策树墩的效果也很不错,但是对于更多特征的样本来说,可能需要很多数量的决策树墩 或许我们可以考虑使用更 ...

  4. .net 中读取自定义Config文件

    今天做一个windows插件式服务程序,插件有时要读取配置文件的设置,但是服务是动态加载到服务上的,没有办法作到动态修改服务的配置文件(app.config).在.net 2.0中有一个Configu ...

  5. UnityShader快速上手指南(四)

    简介 由于其他项目中断了几天更新,继续~~ 这一篇主要是讲光照的(包含漫反射和高光以及多光源的处理) 还是先来看看具体效果(多光源后面单独展示) 有了基本的光照处理之后越来越有立体感了有不有 ╮(╯▽ ...

  6. ANT自动打包U3D安卓项目研究笔记

    概述 因项目使用Atlassian Stash作为项目源码管理端,且其支持Ant命令自动编译,可使其根据最新的代码自动打包,故产生该研究Ant打包的任务.在此将研究过程及一些相关知识整理记录在此. 本 ...

  7. Try out the latest C++ compiler toolset without waiting for the next update of Visual Studio

    Updated 22/Apr/2016: The NuGet package is now being uploaded daily. The payload doesn’t change every ...

  8. Windows server 2008 r2搭建FTP服务器

    最近需要搭建FTP服务器,顺着书上的教程走一遍流程. 1. 安装FTP服务 图一 图二 图三 可以看到上面提示并未启动windows自动更新,这个需要注意一下. 2. 新建FTP站点 准备FTP文件夹 ...

  9. VS2010 根据模型生成数据库 打开edmx.sql文件时 vs出现无响应的解决方案

    今天在VS2010 sp1+sql server 2008 R2+Win7操作系统下测试ADO.NET 实体数据模型时 ,遇到这样一个问题. 首先建好实体模型,然后"根据模型生成数据库&qu ...

  10. python代码风格-PEP8

    转载自http://www.douban.com/note/134971609/ Python 的代码风格由 PEP 8 描述.这个文档描述了 Python 编程风格的方方面面.在遵守这个文档的条件下 ...