iOS-Swift分类视图

//
//  PDLinkageView.swift
//  ShenKang
//
//  Created by 裴铎 on 2019/4/29.
//  Copyright © 2019 apple. All rights reserved.
//

import UIKit
import RxSwift
import RxCocoa

class PDLinkageView: UIView {

    ///标题s数组
    var titles : [String] = [String]()
    /** 存放子控制器对象的数组,内部的元素个数必须和标题数组内的一致 */
    var allViewControllers : [UIViewController] = [UIViewController]()
    ///上一次被点击的按钮
    fileprivate var previousClickButton = UIButton()
    ///默认选中的按钮d下标
    fileprivate var defaultButtonIndex : Int = 0
    ///空间标识符
    fileprivate let identifierTag = 2019429 //2019/4/29.
    ///垃圾袋
    fileprivate lazy var bag = DisposeBag()
    ///下划线的默认宽度
    fileprivate let titleUnderlineWidth : CGFloat = 30
    ///标题视图
    lazy var titlesView : UIView = {
        let titlesView = UIView(frame: CGRect(x: 0, y: 0, width: self.pd_width, height: 44))
        titlesView.backgroundColor = .white
        /** 获取应该添加的按钮个数 */
        let buttonCount : CGFloat = CGFloat(self.titles.count);
        /** 循环添加按钮 */
        for (index, title) in self.titles.enumerated() {
            let button = UIButton(type: .custom)
            let buttonWidth = titlesView.pd_width / buttonCount
            button.frame = CGRect(x: CGFloat(index) * buttonWidth, y: 0, width: buttonWidth, height: titlesView.pd_height)
            button.setTitle(title, for: .normal)
            button.setTitleColor(UIColor.black, for: .normal)
            button.setTitleColor(UIColor.blue, for: .selected)
            button.tag = index + self.identifierTag
            button.rx.tap.subscribe(onNext: {[weak self] (_) in
                self?.titleButtonClick(button: button)
            }).disposed(by: self.bag)
            titlesView.addSubview(button)
        }
        return titlesView
    }()
    ///下划线
    lazy var titleUnderline : UIView = {
        let titleUnderline = UIView()
        /** 拿到标题视图上的某一个按钮, 用来获取按钮上的状态信息 */
        guard let button = self.titlesView.subviews.first as? UIButton else {
            return titleUnderline
        }
        titleUnderline.backgroundColor = button.titleColor(for: .selected)
        titleUnderline.pd_height = 2
        titleUnderline.pd_width = button.titleLabel?.pd_width ?? self.titleUnderlineWidth
        titleUnderline.pd_y = button.pd_height - 2
        titleUnderline.pd_centerX = self.titlesView.subviews[self.defaultButtonIndex].pd_centerX
        return titleUnderline
    }()
    ///主体滚动视图
    lazy var mainScrollView : UIScrollView = {
        let mainScrollView = UIScrollView(frame: CGRect(x: 0, y: self.titlesView.pd_bottom, width: self.pd_width, height: self.pd_height - self.titlesView.pd_height))
        mainScrollView.backgroundColor = UIColor.gray
        mainScrollView.contentSize = CGSize(width: self.pd_width * CGFloat(self.titles.count), height: self.pd_height - self.titlesView.pd_height)
        mainScrollView.isPagingEnabled = true
        mainScrollView.delegate = self
        mainScrollView.scrollsToTop = false
        mainScrollView.showsVerticalScrollIndicator = false
        mainScrollView.showsHorizontalScrollIndicator = false
        mainScrollView.contentOffset = CGPoint(x: self.pd_width * CGFloat(self.defaultButtonIndex), y: 0)
        return mainScrollView
    }()
    
    
}
// MARK:- 自定义构造器
extension PDLinkageView {
    
    /// 自定义构造器
    ///
    /// - Parameters:
    ///   - frame: 尺寸位置
    ///   - titles: 标题按钮显示文字数组
    ///   - allViewControllers: 所有的子控制器(和标题数组的元素个数要相同)
    ///   - defaultButtonIndex: 默认选中的按钮下标 默认:0
    convenience init(frame: CGRect, titles : [String], allViewControllers :  [UIViewController], _ defaultButtonIndex : Int = 0) {
        self.init(frame: frame)
        self.titles = titles
        self.allViewControllers = allViewControllers
        self.defaultButtonIndex = defaultButtonIndex
        guard titles.count > 0 else {
            fatalError("titles不能为空")
        }
        guard titles.count == allViewControllers.count else {
            fatalError("标题按钮和s实际的子控制器个数不相同")
        }
        guard defaultButtonIndex < titles.count else {
            fatalError("默认选中的按钮下标越界")
        }
        self.setUI()
    }
}
// MARK:- UI
extension PDLinkageView {
    fileprivate func setUI() {
        self.addSubview(titlesView)
        self.addSubview(titleUnderline)
        self.addSubview(mainScrollView)
        let button = titlesView.subviews[defaultButtonIndex] as! UIButton
        titleButtonClick(button: button)
    }
    ///加载子控制器视图
    fileprivate func setupChildViewController(index : Int){
        guard allViewControllers.count > 0 else {
            return;/** 没有子控制器时不要执行下面的代码 */
        }
        /** 获取到索引对应的子控制器 */
        let childVC = allViewControllers[index]
        
        /** 判断控制器是否被加载过 */
        guard childVC.isViewLoaded == false else {
            return
        }
        /** 获取子控制器的视图 */
        guard let childView = childVC.view else {
            return
        }
        
        /** 判断视图是否被加载过,判断childView是否有父控件,如果有说明被加载过 */
        guard childView.superview == nil else {
            return
        }
        guard childView.window == nil else {
            return
        }
        /** 设置视图的frame */
        childView.frame = mainScrollView.bounds;
        /** 加载到滚动视图上 */
        mainScrollView.addSubview(childView)
        
    }
}
// MARK:- 事件
extension PDLinkageView {
    func titleButtonClick(button : UIButton) {
        /** 取消上一次点击的按钮选中状态 */
        previousClickButton.isSelected = false
        button.isSelected = true
        previousClickButton = button
        let index = button.tag - self.identifierTag
        UIView.animate(withDuration: 0.25, animations: {
            self.titleUnderline.pd_width = button.titleLabel?.pd_width ?? self.titleUnderlineWidth
            self.titleUnderline.pd_centerX = button.pd_centerX
            let offsetX = self.mainScrollView.pd_width * CGFloat(index)
            self.mainScrollView.contentOffset = CGPoint(x: offsetX, y: self.mainScrollView.contentOffset.y)
        }) { (finish) in
            self.setupChildViewController(index: index)
        }
    }
}
// MARK:- 滚动视图代理协议
extension PDLinkageView : UIScrollViewDelegate {
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        /** 求出应该点击的按钮的索引 */
        let index = scrollView.contentOffset.x / scrollView.pd_width;
        let button = titlesView.subviews[Int(index)] as! UIButton
        titleButtonClick(button: button)
    }
}

你可能感兴趣的:(iOS-Swift分类视图)