专栏首页技术总结教你制作可移动的导航栏

教你制作可移动的导航栏

前言:

目前可移动的导航栏非常常见,以网易、京东、淘宝为首,都用到了此类导航栏,即可以左右滑动,选择更多。见下图紫色圈内

网易新闻客户端

本文将会介绍这类导航栏的做法,方法很多,但关键思路是一样的,希望给大家带来帮助

一、最顶的滚动条

上面可移动的那个条,我们会想到带有滚动功能的控件,无非就是UITableViewUICollectionViewUIScrollView,在此,我们优先选择scrollView,至于那一个个栏目,我的思路是UIButton即可。如果选择的是UICollectionView,那一个个栏目便是UICollectionView的item

1、创建常量

private let titleWidth : CGFloat = 80
private let titleHeight : CGFloat = 40
private let ScreenWidth = UIScreen.main.bounds.size.width
private let ScreenHeight = UIScreen.main.bounds.size.height

2、创建属性

private var selectButton:UIButton?//选择的栏目
private var sliderView:UIView?//指示器
private var topScroll:UIScrollView?
var titleArray = [String]()//暂存栏目title
var buttonArray = [UIButton]() //暂存所有栏目

3、创建滚动条

func createScrollableTopBar(){
    
    //滑动ScrollView
    let scroll = UIScrollView(frame: CGRect(x: 0, y: 0, width:self.ScreenWidth, height: self.titleHeight))
    scroll.contentSize = CGSize(width: self.titleArray.count * NSInteger(titleWidth), height: 40)
    scroll.bounces = false
    scroll.showsHorizontalScrollIndicator = false
    scroll.flashScrollIndicators()
    scroll.backgroundColor = UIColor.gray
    self.view.addSubview(scroll)
    self.topScroll = scroll
    
    //栏目按钮
    for(index,value) in self.titleArray.enumerated(){
        let titleButton = UIButton(frame: CGRect(x: self.titleWidth * CGFloat(index), y: 0, width: self.titleWidth, height: self.titleHeight))
        titleButton.setTitle(value, for: .normal)
        titleButton.setTitleColor(UIColor.black, for: .normal)
        titleButton.backgroundColor = UIColor.white
        titleButton.tag = 100 + index
        titleButton.titleLabel?.font = UIFont.systemFont(ofSize: 14)
        scroll.addSubview(titleButton)
        self.buttonArray.append(titleButton)
    }
        
}

效果如下:

4、添加选中时的颜色和滑块指示器

for(index,value) in self.titleArray.enumerated(){}循环中,添加

if(index == 0){
    self.selectButton = titleButton
    self.selectButton?.setTitleColor(UIColor.orange, for: .normal)
}

createScrollableTopBar最底下,添加

//滑块 indicator
let sliderView = UIView(frame: CGRect(x: 15, y: self.titleHeight - 2, width: self.titleWidth - 20, height: 2))
sliderView.backgroundColor = UIColor.orange
scroll.addSubview(sliderView)
self.sliderView = sliderView;

效果如下:

5、选中栏目时所触发的方法 在createScrollableTopBartitleButton添加点击方法

titleButton.addTarget(self, action: #selector(scrollViewSelectToIndex), for:.touchUpInside)

完成点击方法里面的内容:

1、为每个栏目设置tag值 2、为每个选中的栏目设置背景颜色为orange 3、为了人性化,选中的栏目尽可能移到界面中间。 这也是本文重点:根据选中的栏目(按钮),分别为topScroll设置不同的ContentOffset,主要有三种情况:一、选中的栏目是前几个 二、选中的栏目时后几个 三、选中其他栏目 前两种情况没办法偏移到界面中间

/**选择某个项目*/
func selectButton(index:NSInteger){
    //把当前的按钮重置为原来颜色
    self.selectButton?.setTitleColor(UIColor.black, for: .normal)
    //取出选中的按钮
    selectButton = self.buttonArray[index]
    self.selectButton?.setTitleColor(UIColor.orange, for: .normal)
    // 将rect由rect所在视图转换到目标视图view中,返回在目标视图view中的rect  相对于当前显示窗口
    let rect = selectButton!.superview!.convert(selectButton!.frame, to: self.view)
    UIView .animate(withDuration: 0) {
        let contentOffset = self.topScroll!.contentOffset;
        //选中栏目的最前几个:scrollView偏移值 + 那个按钮的X值 <= 当前显示窗口中间X值
        if contentOffset.x <= (self.ScreenWidth/2 - rect.origin.x - self.titleWidth/2)  {
            print("1")
            self.topScroll!.setContentOffset(CGPoint(x:0,y:contentOffset.y), animated: true)
            //(self.ScreenWidth/2 - rect.origin.x - self.titleWidth/2) 判断选中的按钮是在左边还是右边
        } else if (rect.origin.x - self.ScreenWidth/2 + self.titleWidth/2) >= CGFloat(self.titleArray.count) * self.titleWidth - self.ScreenWidth - contentOffset.x { //选中栏目的最后几个: 那个按钮的X值 -当前显示窗口中间X值 + 栏目的一半,即scrollView偏移值 >= 总栏目的长 - self.ScreenWidth - 偏移量contentOffset.x
            self.topScroll!.setContentOffset(CGPoint(x:CGFloat(self.titleArray.count) * self.titleWidth - self.ScreenWidth,y:contentOffset.y), animated: true)
            print("2")
        } else {
            print("3")//
            self.topScroll!.setContentOffset(CGPoint(x:contentOffset.x - (self.ScreenWidth/2 - rect.origin.x - self.titleWidth/2),y:contentOffset.y), animated: true)
        }
    }
}

现在,点击任意一个栏目,栏目(按钮)的背景色都会变成橙色,而上一个选中的栏目会变成原来的灰色 效果如下:

6、选中

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • MJRefresh源码剖析与学习

    建议查看原文:https://www.jianshu.com/p/23c876f8ae39(不定时更新)

    Dwyane
  • 教你如何自定义AlertView

    Dwyane
  • DWIntrosPage 简单定制引导页

    下面摘取部分代码 DWIntrosPageContentViewController

    Dwyane
  • Python学习——数据模型/特殊方法

    数据模型其实是对Python框架的描述,它规范了这门语言自身构架模块的接口,这些模块包括但不限于序列、迭代器、函数、类和上下文管理器。简单来说,数据模型就是Py...

    陆勤_数据人网
  • vn.py入门-低买高卖示例

    本文用一个例子来介绍vnpy的用法。从项目创建开始,到一个简单策略的设计。 这个例子连接到CTP接口,每秒检查一下目标合约的价格,若低于指定价格则买入,若高于指...

    用Python的交易员
  • 多线程如何获取结果

    "Do what you feel in your heart to be right. You’ll be criticized anyway.—— Elea...

    小闫同学啊
  • 干货 | 时间序列数据的对齐和数据库的分批查询

    在机器学习里,我们对时间序列数据做预处理的时候,经常会碰到一个问题:有多个时间序列存在多个表里,每个表的的时间轴不完全相同,要如何把这些表在时间轴上进行对齐,从...

    用户1621951
  • Python 面向对象设计 - 腾讯即时通信以及微信示例

    Devops海洋的渔夫
  • python的tkinter编程(九)Text多行文本框的详细解读

    一天不写程序难受
  • 用Python 优雅的打飞机

    相信很多朋友都用java 写过飞机大战,在自己学完python基础以后就开始写python版飞机大战,今天把用pygame实现飞机大战的游戏分享给大家。

    PM小王

扫码关注云+社区

领取腾讯云代金券