// // MPPositive_SearchHistoryView.swift // relax.offline.mp3.music // // Created by Mr.Zhou on 2024/8/7. // import UIKit ///搜索历史 class MPPositive_SearchHistoryView: UIView { //历史标签 private lazy var historyLabel:UILabel = createLabel("History", font: .systemFont(ofSize: 14*width, weight: .regular), textColor: .init(hex: "#666666"), textAlignment: .left) //删除按钮 private lazy var deleteBtn:UIButton = { let btn:UIButton = .init() btn.setBackgroundImage(UIImage(named: "Tag_Delete'logo"), for: .normal) btn.addTarget(self, action: #selector(deleteClick(_ :)), for: .touchUpInside) return btn }() //搜索历史展示 private lazy var collectionView:UICollectionView = { let layout = MPPositive_TagFlowLayout() layout.delegate = self let collectionView:UICollectionView = .init(frame: .init(x: 0, y: 0, width: screen_Width, height: screen_Height), collectionViewLayout: layout) collectionView.showsVerticalScrollIndicator = false collectionView.showsHorizontalScrollIndicator = false collectionView.backgroundColor = .clear collectionView.dataSource = self collectionView.delegate = self collectionView.register(MPPositive_SearchTagCollectionViewCell.self, forCellWithReuseIdentifier: MPPositive_SearchTagCollectionViewCellID) return collectionView }() private let MPPositive_SearchTagCollectionViewCellID = "MPPositive_SearchTagCollectionViewCell" //历史数据 private var historys:[MPPositive_SearchTagModel] = [] var selectedTagBlock:((String) -> Void)? override init(frame: CGRect) { super.init(frame: frame) confirgue() } private func confirgue() { backgroundColor = .clear //添加控件 addSubview(deleteBtn) deleteBtn.snp.makeConstraints { make in make.width.height.equalTo(24*width) make.right.equalToSuperview().offset(-18*width) make.top.equalToSuperview().offset(24*width) } addSubview(historyLabel) historyLabel.snp.makeConstraints { make in make.centerY.equalTo(deleteBtn) make.left.equalToSuperview().offset(18*width) } addSubview(collectionView) collectionView.snp.makeConstraints { make in make.top.equalTo(deleteBtn.snp.bottom).offset(6*width) make.left.bottom.right.equalToSuperview() } } //更新搜索历史数据 func reloadHistory() { MPPositive_LoadCoreModel.shared.reloadSearchTags { [weak self] in guard let self = self else {return} historys = MPPositive_LoadCoreModel.shared.searchTags collectionView.reloadData() } } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } //删除按钮 @objc private func deleteClick(_ sender:UIButton) { //移除所有 historys.forEach { item in MPPositive_SearchTagModel.delete(item) } guard let layout = collectionView.collectionViewLayout as? MPPositive_TagFlowLayout else {return} layout.originxArray.removeAll() layout.originyArray.removeAll() layout.layoutAttributeds.removeAll() MPPositive_LoadCoreModel.shared.reloadSearchTags { [weak self] in guard let self = self else {return} historys = MPPositive_LoadCoreModel.shared.searchTags collectionView.reloadData() } } } //MARK: - collectionView extension MPPositive_SearchHistoryView: UICollectionViewDataSource, UICollectionViewDelegate, MPPositive_TagLayoutDelegate { func waterFlowLayout(_ layout: MPPositive_TagFlowLayout, indexPath: IndexPath) -> CGFloat { if indexPath.row < historys.count { let text = historys[indexPath.row].text ?? "" let textWidth = text.textAutoWidth(height: 11.5 * width, font: .systemFont(ofSize: 12 * width, weight: .medium)) + (43 * width) return textWidth }else { return 0 } } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return historys.count > 10 ? 10:historys.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MPPositive_SearchTagCollectionViewCellID, for: indexPath) as! MPPositive_SearchTagCollectionViewCell cell.setText(historys[indexPath.row].text ?? "") return cell } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { MPPositive_Debouncer.shared.call { [weak self] in guard let self = self else {return} if let text = historys[indexPath.row].text, let block = selectedTagBlock { block(text) } } } } //MARK: - 宽度代理 protocol MPPositive_TagLayoutDelegate { func waterFlowLayout(_ layout:MPPositive_TagFlowLayout,indexPath:IndexPath) -> CGFloat } //MARK: - 重写布局 ///标签layout class MPPositive_TagFlowLayout: UICollectionViewFlowLayout { //固定行高 var rowHeight:CGFloat = 22 * width //宽度获取代理 var delegate:MPPositive_TagLayoutDelegate? //x值数组 var originxArray:[CGFloat]! //y值数组 var originyArray:[CGFloat]! //记录的布局值 var layoutAttributeds:[UICollectionViewLayoutAttributes] = [] override init() { super.init() //列间距 minimumInteritemSpacing = 8 * width //行间距 minimumLineSpacing = 8 * width //内边距 sectionInset = .init(top: 5 * width, left: 18 * width, bottom: 5 * width, right: 18 * width) scrollDirection = .vertical //初始化数组 originxArray = [CGFloat]() originyArray = [CGFloat]() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } //MARK: - 重写父类方法,实现瀑布流布局 //当尺寸发生变化时,刷新布局 override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool { return true } override func prepare() { super.prepare() } //处理所有item的layoutAttributes override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { let array = super.layoutAttributesForElements(in: rect) var mutArray = [UICollectionViewLayoutAttributes]() array?.forEach({ (attrs) in if let theAttrs = layoutAttributesForItem(at: attrs.indexPath) { mutArray.append(theAttrs) } }) layoutAttributeds = mutArray return mutArray } //处理单个item的layoutAttributes override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { //起始x值 var x = sectionInset.left var y = sectionInset.top //判断获得前一个cell的x和y let preRow = indexPath.row - 1 if preRow >= 0 { //不是第一个cell if originyArray.count > preRow { //更新x和y值 x = originxArray[preRow] y = originyArray[preRow] } let preIndexPath = IndexPath(item: preRow, section: indexPath.section) //计算宽度 let preWidth = delegate?.waterFlowLayout(self, indexPath: preIndexPath) x += preWidth! + minimumInteritemSpacing } var currentWidth = delegate?.waterFlowLayout(self, indexPath: indexPath) //保证每一个cell不超过最大宽度 currentWidth = min(currentWidth!, collectionView!.frame.size.width - sectionInset.left - sectionInset.right) if x + currentWidth! > collectionView!.frame.size.width - sectionInset.right { //超出范围,换行 x = self.sectionInset.left y += rowHeight + minimumLineSpacing } //创建属性 let attrs = UICollectionViewLayoutAttributes.init(forCellWith: indexPath) attrs.frame = CGRect(x: x, y: y, width: currentWidth!, height: rowHeight) originxArray.insert(x, at: indexPath.row) originyArray.insert(y, at: indexPath.row) return attrs } }