Swift创建类似于今日头条的分类导航界面

一:效果

 

 

二:实现步骤

1、布局分类导航控件代码

// 添加分类导航子控件
    func addCategorNavSVw() -> Void {
        if categoryNavSVw == nil {
            // 用于存放分类导航标题的UIScrollView
            categoryNavSVw = UIScrollView()
            self.view.addSubview(categoryNavSVw!)
            categoryNavSVw!.snp.makeConstraints { (make) in
                make.top.equalTo(self.orgBgVw!.snp.bottom).offset(20)
                make.left.equalTo(10)
                make.right.equalTo(-10)
                make.height.equalTo(35)
                make.width.equalTo(Contants.SCREENWITH)
            }
            vw.backgroundColor = HDColor(red: 80, green: 151, blue: 153, alpha: 1).color
            self.categoryNavSVw!.addSubview(vw)
            // 添加约束
            vw.snp.makeConstraints { (make) in
                make.top.bottom.left.equalTo(0)
                make.height.equalTo(self.categoryNavSVw!.snp.height)
                make.width.equalTo(Int((Contants.SCREENWITH-20)/5))
            }
            // 切圆角
            vw.layer.cornerRadius = 16
            let navTitleArr = ["首页","云相册","视频","人物识别","同学"]
            // 循环添加子控件,选用button作为分类导航标题的控件是为了方便添加点击事件
            for i in 0...4{
                let btn = UIButton()
                btn.setTitle(navTitleArr[i], for: .normal)
                btn.titleLabel?.font = UIFont.systemFont(ofSize: 14)
                btn.setTitleColor(UIColor.black, for: .normal)
                if i == 0{
                    btn.setTitleColor(UIColor.white, for: .normal)
                    
                }
                btn.tag = 1000 + i
                self.categoryNavSVw!.addSubview(btn)
                // 添加约束
                btn.snp.makeConstraints { (make) in
                    make.top.bottom.equalTo(0)
                   // 这句约束是让每个分类导航子控件平分父控件的位置
                    make.left.equalTo(Int((Contants.SCREENWITH-20)/5)*i)
                    make.width.equalTo(Int((Contants.SCREENWITH-20)/5))
                }
                // 为每一个子控件添加点击事件
                btn.addTarget(self, action: #selector(navTitleAction), for: .touchUpInside)
               // 分类导航子控件添加到一个全局数组中,方便处理点击事件
              self.categoryBtnArr.append(btn)
            }
            
        }
        
    }

2、布局分类导航内容控件代码

 // 添加分类内容svw
    func addContentSVw(){
        if contentSVw == nil {
            // 分类导航内容UIScrollView
            contentSVw = UIScrollView()
            // 分页滑动
            contentSVw?.isPagingEnabled = true
            // 禁止碰撞效果
            contentSVw?.bounces = false
            // 设置代理
            contentSVw?.delegate = self
            // 去除水平滑动线
            contentSVw?.showsHorizontalScrollIndicator = false
            // 去除垂直滑动线
            contentSVw?.showsVerticalScrollIndicator = false
            contentSVw?.backgroundColor = .blue
            // 设置分类内容的大小,宽度一定要设置为屏幕的宽度*分类的个数
            contentSVw?.contentSize = CGSize(width: Contants.SCREENWITH * 5, height: Contants.SCREENHEIGHT-500)
            self.view.addSubview(contentSVw!)
            contentSVw!.snp.makeConstraints { (make) in
                make.top.equalTo(self.categoryNavSVw!.snp.bottom).offset(20)
                make.left.right.equalTo(0)
                make.bottom.equalTo(self.view.snp.bottom).offset(-20)
                make.width.equalTo(Contants.SCREENWITH)
            }
            
            for i in 0...4{
                // 循环添加分类的子view
                let svw = UIView()
                if i==0 {
                    svw.backgroundColor = .red
                }
                if i==1 {
                    svw.backgroundColor = .blue
                }
                if i==2 {
                    svw.backgroundColor = .yellow
                }
                if i==3 {
                    svw.backgroundColor = .purple
                }
                if i==4 {
                    svw.backgroundColor = .brown
                }
                self.contentSVw!.addSubview(svw)
                // 添加约束
                svw.snp.makeConstraints { (make) in
                    make.top.equalTo(0)
                    make.height.equalTo(self.contentSVw!.snp.height)
                    make.width.equalTo(Contants.SCREENWITH)
                  // 这句约束在于分类内容的子控件平分分类父控件的contentSize
                    make.left.equalTo(Int(Contants.SCREENWITH)*i)
                }
                
                
            }
        }
    }

3、添加分类导航标题于分类导航内容联动的点击事件

    // 分类导航点击按钮事件
    @objc func navTitleAction(btn:UIButton){
        // 之前为btn添加的tag值为的是获取分类内容与分类标题的位置
        let tag = btn.tag - 1000
        
        for categoryBtn in self.categoryBtnArr{
            // 循环判断当前点击的btn是否与btn数组中的btn是否相等
            if categoryBtn.tag == btn.tag {
                // 如果相等改变选中btn的字体颜色
                categoryBtn.setTitleColor(UIColor.white, for: .normal)
                // 改变btn的背景View位置
                UIView.animate(withDuration: 0.4) {
                    // 更新约束
                    self.vw.snp.updateConstraints { (make) in
                        make.top.bottom.equalTo(0)
                        make.height.equalTo(self.categoryNavSVw!.snp.height)
                        make.width.equalTo(Int((Contants.SCREENWITH-20)/5))
                        make.left.equalTo(Int((Contants.SCREENWITH-20)/5)*tag)
                    }
                     // 这句至关重要,是使约束的动画产生效果
                    self.view.layoutIfNeeded()
                }
                 // 展示相应的分类内容位置
                UIView.animate(withDuration: 0.5) {
                    
                    self.contentSVw!.setContentOffset(CGPoint(x: Int(Contants.SCREENWITH) * tag, y: 0), animated: true)
                    
                }
                
            }else{
                // 未选择中的btn的字体颜色
                categoryBtn.setTitleColor(UIColor.black, for: .normal)
                
            }
        }
    }
    
}


版权声明:本文为xiayong763541原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。