美文网首页
iOS-Swift分类视图

iOS-Swift分类视图

作者: 长衣貌 | 来源:发表于2019-05-16 19:07 被阅读0次
    //
    //  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分类视图

          本文链接:https://www.haomeiwen.com/subject/ivjwaqtx.html