swift 标签

 

 

import UIKit

 

public protocol YPLabelsItemView:UIView{

    /// 最大的宽

    func labelItemWidth(with data:Any) -> CGFloat

}

 

public protocol YPLabelsViewDelegate : AnyObject{

    /// 选中某个标签回调

    func labelsView(didSelectAt index: Int,with itemView:YPLabelsItemView, data:Any)

}

 

public class YPLabelsView<V:YPLabelsItemView>: YPBaseView {

    /// 每一个item的高度

    let itemHight : CGFloat

    /// 最多展示几行

    public var numberOfLines : Int = 0{

        didSet{

            resetSubItemsFrame()

        }

    }

    /// 间距

    public let spacing : CGFloat

    /// 行间距

    public let rowSpacing : CGFloat

    /// 数据源

    public private(set) var data : [Any] = []

    /// 代理

    public weak var delegate : YPLabelsViewDelegate?

    /// 内容高度

    public var contentHeight : CGFloat{

        for view in subviews.reversed() {

            if !view.isHidden {

                return view.wp.maxY

            }

        }

        return 0

    }

 

    /// 初始化标签视图

    /// - Parameters:

    ///   - itemHeight: item高度

    ///   - spacing: 列间距

    ///   - rowSpacing: 行间距

    public init(itemHeight: CGFloat,

                spacing:CGFloat = 10,

                rowSpacing:CGFloat = 10) {

        self.itemHight = itemHeight

        self.spacing = spacing

        self.rowSpacing = rowSpacing

        super.init(frame: .zero)

        isUserInteractionEnabled = true

    }

    

    required init?(coder: NSCoder) {

        fatalError("init(coder:) has not been implemented")

    }

    

    /// 设置数据源

    /// - Parameter data: 数据类型

    public func set(data:[Any]){

        self.data = data

        subviews.forEach { elmt in

            elmt.removeFromSuperview()

        }

        for index in 0..<data.count {

            let elmt = data[index]

            let subView = V.init(frame: .zero)

            let tap = UITapGestureRecognizer()

            subView.addGestureRecognizer(tap)

            tap.rx.event.subscribe(onNext: {[weak self] _ in

                self?.delegate?.labelsView(didSelectAt: index, with: subView, data: elmt)

            }).disposed(by: subView.wp.disposeBag)

            

            subView.isUserInteractionEnabled = true

            subView.frame = .init(x: 0, y: 0, width: subView.labelItemWidth(with: elmt), height: itemHight)

            subView.tag = index

            addSubview(subView)

        }

        layoutIfNeeded()

    }

 

    /// 删除某个标签

    public func remove(at index:Int){

        data.wp_remove(at: index)

        reloadData()

    }

 

    /// 增加标签

    public func append(_ elmt : Any){

        data.append(elmt)

        reloadData()

    }

 

    /// 插入某个标签

    public func insert(_ elmt : Any,at:Int){

        data.wp_insert(elmt, at: at)

        reloadData()

    }

 

    /// 刷新数据源

    public func reloadData(){

        set(data: data)

    }

 

    private func resetSubItemsFrame(){

        let maxWidth = self.wp.width

 

        var y : CGFloat = 0

        var row : CGFloat = 0

        var rowX : CGFloat = 0

 

        subviews.forEach { elmt in

            elmt.wp_orgin = .zero

            elmt.isHidden = false

        }

 

        for index in 0..<subviews.count {

            let lastX = subviews.wp_get(of: index - 1)?.wp_maxX ?? 0

 

            let view = subviews[index] as! V

            let width = view.labelItemWidth(with: data[index])

 

            if lastX + width + spacing > maxWidth{

                row = row + 1

                rowX = 0

            }

 

            y = row * (itemHight + rowSpacing)

 

            view.wp_orgin = .init(x: rowX, y: y)

 

            rowX = spacing + width + rowX

 

            view.isHidden = (numberOfLines != 0 && Int(row) + 1 > numberOfLines)

        }

    }

 

    public override func layoutSubviews() {

        super.layoutSubviews()

 

        resetSubItemsFrame()

    }

}

 

//-------------- 使用到的方法1 ------------

    /// 安全获取一个元素

    /// - Parameter index: 所有

    /// - Returns: 元素

    func wp_get(of index: Int)->Element? {

        if index <= count - 1, index >= 0 {

            return self[index]

        } else {

            return nil

        }

    }

 

posted @ 2022-03-08 09:32  super1250  阅读(55)  评论(0编辑  收藏  举报