209 lines
8.4 KiB
Swift
209 lines
8.4 KiB
Swift
//
|
||
// 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
|
||
}
|
||
}
|