iOS实现顶部标签式导航栏及下拉分类菜单

本文实例为大家分享了iOS实现顶部标签式导航栏及下拉分类菜单的全部过程,供大家参考,具体内容如下

当内容及分类较多时,往往采用顶部标签式导航栏,例如网易新闻客户端的顶部分类导航,最近刚好有这样的应用场景,参考网络上一些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中进行判断处理的。

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

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

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

2.下拉分类菜单

(1)使用场景及方式

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

(2)UI元素分解

一个放在导航栏旁边的按钮dropDownButton,一个titleView,以及下拉分类菜单dropDownCategoryListView,里面包含一个collectionView展示分类数,据。dropDownButton控制titleView及dropDownCategoryListView的显示,dropDownCategoryListView背景色设置一定透明度做背景。接下来总结一下几个关键点。

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

这里每一行显示三个分类数据,分类数量及cell高度确定后即可确定collectionView的高度,即先确定纵向有几行分类数据,行数xcell高度就是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再收起菜单即可。

以上就是本文的全部内容,希望对大家的学习有所帮助。

(0)

相关推荐

  • iOS 自定义状态栏和导航栏详细介绍

    iOS 自定义状态栏和导航栏 开发IOS APP 经常会根据需求更改状态栏和导航栏,这里整理了几种方法,大家可以看下. 导航栏透明 -(void)viewWillAppear:(BOOL)animated { //viewWillAppear中设置透明 [super viewWillAppear:animated]; [self.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault]; /

  • iOS界面跳转时导航栏和tabBar的隐藏与显示功能

    一.当A页面要push到B页面,需要将B页面的导航栏隐藏时,我们只需要在A页面中重写以下两个方法: override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) self.navigationController?.setNavigationBarHidden(true, animated: true) } override func viewWillDisappear(animated: Bool)

  • iOS如何为导航栏添加播放动画

    本文实例为大家分享了iOS为导航栏添加播放动画的具体代码,供大家参考,具体内容如下 FLAudioVisualizerView.h #import <UIKit/UIKit.h> @interface FLAudioVisualizerView : UIView #pragma mark - // 默认UIEdgeInsetsZero @property (nonatomic, assign) UIEdgeInsets contentInsets; // 默认为4 @property (non

  • iOS App开发中导航栏的创建及基本属性设置教程

    文件目录如下:基本导航顺序: root -> First -> Second -> Third.其中,FirstViewController作为 navigation堆栈的rootview 1.创建navigation 如果是想直接把navigation导航作为项目一开始的跟视图,把RootViewController.h文件里的nav属性放到AppDelegate.h里即可,再把RootViewController.m文件里的action的代码复制到 AppDelegate.m里的di

  • 两种iOS隐藏导航栏的正确方法

    简介 在项目中经常碰到首页顶部是无限轮播,需要靠最上面显示.有的设置导航栏为透明等一系列的方法,这个可以借助第三方.或者干脆简单粗暴的直接隐藏掉导航栏.可是push到下一个页面的时候是需要导航栏的,如何做了,这里给出两种方法. 第一种做法 -注意这里一定要用动画的方式隐藏导航栏,这样在使用滑动返回手势的时候效果最好,和上面动图一致.这样做有一个缺点就是在切换tabBar的时候有一个导航栏向上消失的动画. - (void)viewWillAppear:(BOOL)animated { [super

  • iOS实现知乎和途家导航栏渐变的文字动画效果

    效果图如下 分析如下: 1.导航栏一开始是隐藏的,随着scrollView滚动而渐变 2.导航栏左右两边的navigationItem是一直显示的 3.导航栏参考了途家app,使用了毛玻璃效果,背景是一张图片 4.下拉放大图片效果 5.title文字动画效果 通过简单分析,系统的导航栏实现以上效果有点困难,直接自定义一个假的导航栏更容易点 分布拆解实现以上效果 一.下拉放大header图片 - (void)viewDidLoad { [super viewDidLoad]; [self.view

  • iOS如何去掉导航栏(UINavigationBar)下方的横线

    网上有很多关于隐藏的方法,设置后能够成功,但是跳转到其他界面的时候发现,其他界面横线也被隐藏了. 目前主流的方法是将shadowImage用一张空的图片图片替换掉 可是这种方法不能解决navigationController里面的某个界面隐藏,其他不变的问题. [self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault];

  • 关于iOS导航栏返回按钮问题的解决方法

    最近遇到一个关于导航栏返回按钮的问题,因为之前项目里面都是用的系统默认的返回按钮样式所以没有想过要去更改,后来有需要将返回按钮箭头旁边的文字去掉,同时将该返回按钮的点击事件重新定义.一开始尝试自定义按钮然后设置为leftBarButtonItem,但是这样图片可能跟系统自带的不一样,还有就是返回按钮的位置跟系统自带的不一样.后来找了一些资料,发现将文字去掉比较简单,一般做法是控制器中添加如下代码,然后他的下一级控制就有一个只有箭头没有文字返回按钮: 复制代码 代码如下: UIBarButtonI

  • IOS仿今日头条滑动导航栏

    之前在我们平台给大家分享了网易首页导航封装类.网易首页导航封装类优化,今天在前两个的基础上仿下今日头条. 1.网易首页导航封装类中主要解决了上面导航的ScrollView和下面的页面的ScrollView联动的问题,以及上面导航栏的便宜量. 2.网易首页导航封装类优化中主要解决iOS7以上滑动返回功能中UIScreenEdgePanGestureRecognizer与ScrollView的滑动的手势冲突问题. 今天仿今日头条滑动导航和网易首页导航封装类优化相似,这个也是解决手势冲突,UIPanG

  • iOS应用开发中导航栏按钮UIBarButtonItem的添加教程

    1.UINavigationController导航控制器如何使用 UINavigationController可以翻译为导航控制器,在iOS里经常用到. 我们看看它的如何使用: 下面的图显示了导航控制器的流程.最左侧是根视图,当用户点击其中的General项时 ,General视图会滑入屏幕:当用户继续点击Auto-Lock项时,Auto-Lock视图将滑入屏幕.相应地,在对象管理上,导航控制器使用了导航堆栈.根视图控制器在堆栈最底层,接下来入栈的是General视图控制器和Auto-Lock

随机推荐