iOS开发笔记13:顶部标签式导航栏及下拉分类菜单

时间:2022-09-04 14:55:31

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

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

iOS开发笔记13:顶部标签式导航栏及下拉分类菜单

1.顶部标签式导航栏

(1)实现思路

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

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

iOS开发笔记13:顶部标签式导航栏及下拉分类菜单

②顶部导航栏可以用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里需要有一个长度属性,用来记录此长度,方便后续显示,而不用实时去计算长度。

iOS开发笔记13:顶部标签式导航栏及下拉分类菜单

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

iOS开发笔记13:顶部标签式导航栏及下拉分类菜单

(4)内容视图

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

iOS开发笔记13:顶部标签式导航栏及下拉分类菜单

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

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

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

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

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

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

iOS开发笔记13:顶部标签式导航栏及下拉分类菜单iOS开发笔记13:顶部标签式导航栏及下拉分类菜单

先让contentScrollView滑动到指定位置,再通知topCategoryListScrollView滑动。iOS开发笔记13:顶部标签式导航栏及下拉分类菜单

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

iOS开发笔记13:顶部标签式导航栏及下拉分类菜单

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

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

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

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

iOS开发笔记13:顶部标签式导航栏及下拉分类菜单

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

iOS开发笔记13:顶部标签式导航栏及下拉分类菜单

2.下拉分类菜单

(1)使用场景及方式

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

(2)UI元素分解

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

iOS开发笔记13:顶部标签式导航栏及下拉分类菜单

iOS开发笔记13:顶部标签式导航栏及下拉分类菜单

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

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

这里还需要注意一点,默认设置collectionView是不可滑动的,但是需要判断一下分类显示的高度,超出可视范围时,需要允许滑动。iOS开发笔记13:顶部标签式导航栏及下拉分类菜单

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

iOS开发笔记13:顶部标签式导航栏及下拉分类菜单

(4)点击collectionView的事件处理

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

(5)交互效果处理

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

iOS开发笔记13:顶部标签式导航栏及下拉分类菜单

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&period;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&plus;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开发笔记&lpar;swift&rpar;

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

随机推荐

  1. django中migration文件是干啥的

    昨天很蠢的问leader git push的时候会不会把本地的数据库文件上传上去,意思是django中那些migration文件修改之后会不会上传. 然后得知不会,因为所有的数据库都存在本机的mysq ...

  2. Swift - 自动布局库SnapKit的使用详解2(约束的更新、移除、重做)

    在之前的文章中我介绍了如何使用SnapKit的 snp_makeConstraints 方法进行各种约束的设置.但有时我们的页面并不是一直固定不变的,这就需要修改已经存在的约束.本文介绍如何更新.移除 ...

  3. HttpClient通过GET和POST获取网页内容

    中国银行支付网关---银行回调的接口 最简单的HTTP客户端,用来演示通过GET或者POST方式访问某个页面 /** * 中国银行支付网关---银行回调的接口 * @svncode svn://10. ...

  4. WebApi授权拦截——重写AuthorizeAttribute

        跟mvc一样,webapi大多通过附加Authorize特性来实现授权,Authorize当授权失败时返回状态码:401.一般系统状态为401时,服务端就Redirect重定向到登录页.   ...

  5. IDEA建项目的正确姿势

    今天建多模块的分布式项目的时候折腾死了,可能是建项目的方法不对,最后经过摸索,觉得这样是比较合适的: 首先建一个空的项目:Empty Project,就是项目文件夹 然后在里面建model

  6. Linux网络编程&lpar;五&rpar;

    /*Linux网络编程(五)——多路IO复用之select() 网络编程中,使用IO复用的典型场合: 1.当客户处理多个描述字时(交互式输入以及网络接口),必须使用IO复用. 2.一个客户同时处理多个 ...

  7. idea下使用Maven找不到类

    当我们配置好pom文件的时候,准备启动Tomcat,Tomcat缺报找不到类的错误.. 可是明明我们的pom文件是没有问题的,在web.xml中也是可以ctrl+鼠标左键把类找到-为啥就报这么一个错误 ...

  8. No write since last change &lpar;add &excl; to override&rpar;

    故障现象: 使用vim修改文件报错,系统提示如下: E37: No write since last change (add ! to override) 故障原因: 文件为只读文件,无法修改. 解决 ...

  9. 【建项目】eclipse maven建立多模块工程

    在工作的时候,大多时候都是用Maven来管理项目,可是一般我们都知道怎么用maven管理工程,却不知道通过Maven自己来建立多模块工程.于是自己抽时间,在网上找些资料,做了起来. 建立简单的Mave ...

  10. logger 的使用 二logback使用配置详解

    下面是一些最基本的,详细的参考:https://logback.qos.ch/manual/index.html 我的使用:把error日志打印在另一个文件,可以用ELK 统一管理 最近使用: &lt ...