// // MPPositive_SearchViewController.swift // MusicPlayer // // Created by Mr.Zhou on 2024/4/19. // import UIKit class MPPositive_SearchViewController: MPPositive_BaseViewController { //背景图片 private lazy var bgImageView:UIImageView = { let imageView:UIImageView = .init(image: .init(named: "B_Home_BG'bg")) imageView.contentMode = .scaleAspectFill return imageView }() 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 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 }() override func viewDidLoad() { super.viewDidLoad() setTitle("") configure() //加载搜索原生广告 MP_AdMobManager.shared.configureSreachNativeAd(rootController: self) MP_AdMobManager.shared.loadSearchNativeAd() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) MP_AnalyticsManager.shared.search_pvAction() collectionView.reloadData() } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) } //配置 private func configure() { let searchView = createSearchView() navView.addSubview(searchView) searchView.snp.makeConstraints { make in make.width.equalTo(339*width) make.height.equalTo(32*width) make.center.equalToSuperview() } view.addSubview(bgImageView) bgImageView.snp.makeConstraints { make in make.top.right.left.equalToSuperview() make.height.equalTo(981*width) } view.addSubview(deleteBtn) deleteBtn.snp.makeConstraints { make in make.width.height.equalTo(24*width) make.right.equalToSuperview().offset(-18*width) make.top.equalTo(navView.snp.bottom).offset(24*width) } view.addSubview(historyLabel) historyLabel.snp.makeConstraints { make in make.centerY.equalTo(deleteBtn) make.left.equalToSuperview().offset(18*width) } view.addSubview(collectionView) collectionView.snp.makeConstraints { make in make.left.right.equalToSuperview() make.top.equalTo(deleteBtn.snp.bottom).offset(6*width) make.height.equalTo(130*width) } } //生成一个顶部搜索框 private func createSearchView() -> UIView{ let searchView:UIView = UIView() searchView.backgroundColor = .init(hex: "#212121") searchView.isUserInteractionEnabled = true searchView.layer.masksToBounds = true searchView.layer.cornerRadius = 16*width //添加一个icon let iconImageView = UIImageView(image: .init(named: "Search_ICON'logo")) searchView.addSubview(iconImageView) iconImageView.snp.makeConstraints { make in make.height.width.equalTo(16*width) make.left.equalToSuperview().offset(16*width) make.centerY.equalToSuperview() } let label = createLabel("Search songs,artists,playlists", font: .systemFont(ofSize: 14*width, weight: .regular), textColor: .init(hex: "#666666"), textAlignment: .left) searchView.addSubview(label) label.snp.makeConstraints { make in make.left.equalTo(iconImageView.snp.right).offset(8*width) make.centerY.equalToSuperview() } searchView.isUserInteractionEnabled = true searchView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(searchClick(_:)))) return searchView } //前往搜索结果页 @objc fileprivate func searchClick(_ sender:UITapGestureRecognizer) { let resultVC = MPPositive_SearchResultShowViewController() navigationController?.pushViewController(resultVC, animated: false) } //删除按钮 @objc private func deleteClick(_ sender:UIButton) { //移除所有 MPPositive_SearchTagModel.fetchAll().forEach { item in MPPositive_SearchTagModel.delete(item) } MPPositive_LoadCoreModel.shared.reloadSearchTags { [weak self] in guard let self = self else {return} collectionView.reloadData() } } } //MARK: - collectionView extension MPPositive_SearchViewController: UICollectionViewDataSource, UICollectionViewDelegate, MPPositive_TagLayoutDelegate { func waterFlowLayout(_ layout: MPPositive_TagFlowLayout, indexPath: IndexPath) -> CGFloat { let text = MPPositive_LoadCoreModel.shared.searchTags[indexPath.row].text ?? "" let textWidth = text.textAutoWidth(height: 11.5 * width, font: .systemFont(ofSize: 12 * width, weight: .medium)) + (43 * width) return textWidth } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return MPPositive_LoadCoreModel.shared.searchTags.count > 10 ? 10:MPPositive_LoadCoreModel.shared.searchTags.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MPPositive_SearchTagCollectionViewCellID, for: indexPath) as! MPPositive_SearchTagCollectionViewCell cell.setText(MPPositive_LoadCoreModel.shared.searchTags[indexPath.row].text) return cell } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { let text = MPPositive_LoadCoreModel.shared.searchTags[indexPath.row].text ?? "" let resultVC = MPPositive_SearchResultShowViewController(text) navigationController?.pushViewController(resultVC, animated: false) } } //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]! 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 let theAttrs = layoutAttributesForItem(at: attrs.indexPath) mutArray.append(theAttrs!) }) 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 } }