// // PQStuckPointMusicContentController.swift // PQSpeed // // Created by SanW on 2021/4/28. // Copyright © 2021 BytesFlow. All rights reserved. // import UIKit import BFCommonKit class PQStuckPointMusicContentController: PQBaseViewController { var itemList: [Any] = Array.init() // 所有分类数据 // 当前选择的位置 var lastIndexPath: IndexPath? let lineSpacing: CGFloat = 12 let leftMargin: CGFloat = 16 // cell高度 var cellHight: CGFloat = cDefaultMargin * 5 // 顶部距离 var topHight: CGFloat = cDefaultMargin * 6 /// 二级标签信息 var tagsInfo: ([PQStuckPointMusicTagsModel], ([UICollectionViewLayoutAttributes], CGFloat))? // 点击的回调 var didSelectedHandle: ((_ isTagsClick: Bool, _ contentType: stuckPointMusicContentType, _ indexPath: IndexPath, _ itemData: Any) -> Void)? // 按钮点击的回调 var btnClickHandle: ((_ sender: UIButton, _ bgmData: Any?) -> Void)? // 滑动的回调 var scroDidScroHandle: (() -> Void)? // 刷新的回调 var refreshHandle: ((_ isRefresh: Bool, _ contentType: stuckPointMusicContentType) -> Void)? // 卡点音乐页面类型 var contentType: stuckPointMusicContentType = .catagery { didSet { if contentType == .page || contentType == .serach { // SanW - 待修改 - // collectionView.addRefreshView(type: .REFRESH_TYPE_FOOTER) { [weak self] isRefresh in // if self?.refreshHandle != nil { // self?.refreshHandle!(isRefresh, self?.contentType ?? .catagery) // } // } } else { lastIndexPath = IndexPath(item: 0, section: 0) } } } lazy var collectionView: UICollectionView = { let flowLayout = UICollectionViewFlowLayout() flowLayout.sectionInset = UIEdgeInsets.zero flowLayout.minimumLineSpacing = 0 flowLayout.minimumInteritemSpacing = 0 flowLayout.scrollDirection = .vertical let collectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height), collectionViewLayout: flowLayout) collectionView.showsVerticalScrollIndicator = false collectionView.showsHorizontalScrollIndicator = false collectionView.delegate = self collectionView.dataSource = self collectionView.backgroundColor = UIColor.clear collectionView.register(PQStuckPointMusicContentCell.self, forCellWithReuseIdentifier: String(describing: PQStuckPointMusicContentCell.self)) collectionView.register(PQStuckPointMusicTagsCell.self, forCellWithReuseIdentifier: String(describing: PQStuckPointMusicTagsCell.self)) collectionView.register(PQStuckPointSearchEmptyCell.self, forCellWithReuseIdentifier: String(describing: PQStuckPointSearchEmptyCell.self)) if #available(iOS 11.0, *) { collectionView.contentInsetAdjustmentBehavior = .never } else { automaticallyAdjustsScrollViewInsets = false } // 延迟scrollView上子视图的响应,所以当直接拖动UISlider时,如果此时touch时间在150ms以内,UIScrollView会认为是拖动自己,从而拦截了event,导致UISlider接收不到滑动的event collectionView.delaysContentTouches = false collectionView.addRefreshView (type:.REFRESH_TYPE_FOOTER) {[weak self] isRefresh in if !isRefresh && self?.contentType != .catagery{ // 请求一下加载更多 if self?.refreshHandle != nil { self?.refreshHandle!(isRefresh, self?.contentType ?? .catagery) } }else{ collectionView.mj_header?.endRefreshing() } } return collectionView }() lazy var emptyRemindView: PQEmptyRemindView = { let emptyRemindView = PQEmptyRemindView(frame: collectionView.bounds) emptyRemindView.remindLab.font = UIFont.systemFont(ofSize: 16) emptyRemindView.remindLab.textColor = UIColor.hexColor(hexadecimal: "#575757") emptyRemindView.isHidden = true emptyRemindView.emptyData = emptyData emptyRemindView.fullRefreshBloc = { [weak self] _, _ in if self?.refreshHandle != nil { self?.refreshHandle!(true, self?.contentType ?? .catagery) } } collectionView.addSubview(emptyRemindView) return emptyRemindView }() var emptyData: PQEmptyModel? = { let emptyData = PQEmptyModel() emptyData.title = "暂无音乐" emptyData.netDisRefreshBgColor = UIColor.hexColor(hexadecimal: "#FA6400") emptyData.netDisTitle = "内容加载失败" emptyData.netDisTitleColor = UIColor.hexColor(hexadecimal: "#333333") emptyData.netemptyDisImage = UIImage.init(named: "empty_netDis_icon") emptyData.netDisRefreshTitle = NSMutableAttributedString(string: "重新加载", attributes: [.font: UIFont.systemFont(ofSize: 16, weight: .medium), .foregroundColor: UIColor.white]) return emptyData }() override func viewDidLoad() { super.viewDidLoad() hiddenNavigation() view.addSubview(collectionView) } /// 更新frame /// - Parameter newFrame: <#newFrame description#> /// - Returns: <#description#> func updateViewFrame(newFrame: CGRect) { view.frame = newFrame collectionView.frame = CGRect(origin: CGPoint.zero, size: newFrame.size) emptyRemindView.frame = collectionView.bounds collectionView.reloadData() } /// 配置数据 /// - Parameter musicListData: <#musicListData description#> /// - Returns: <#description#> func configMusicListData(isResetData: Bool = false, isRefresh: Bool = true, musicListData: [Any]) { if isRefresh { if contentType == .catagery { lastIndexPath = IndexPath(item: 0, section: 0) } else { lastIndexPath = nil } itemList.removeAll() if tagsInfo != nil { itemList = musicListData itemList.insert(tagsInfo!, at: 0) } else { itemList = musicListData } } else { itemList = itemList + musicListData } if (contentType != .serach && musicListData.count < 20) || (contentType == .serach && musicListData.count <= 0) || itemList.first is PQEmptyModel { collectionView.mj_footer?.endRefreshingWithNoMoreData() } else { collectionView.mj_footer?.endRefreshing() } collectionView.reloadData() // 展示空页面 if isResetData { emptyRemindView.isHidden = true } else { showEmptyView() } } /// 展示空页面 func showEmptyView() { if contentType != .catagery { emptyRemindView.isHidden = contentType == .serach ? itemList.count > 0 : itemList.count > 1 if !emptyRemindView.isHidden, itemList.count > 0, ((itemList.first as? ([PQStuckPointMusicTagsModel], ([UICollectionViewLayoutAttributes], CGFloat)))?.0.count ?? 0) > 0 { let maxH = (((itemList.first as? ([PQStuckPointMusicTagsModel], ([UICollectionViewLayoutAttributes], CGFloat)))?.1.1 ?? 0) + 35) emptyRemindView.frame = CGRect(x: 0, y: maxH, width: collectionView.frame.width, height: collectionView.frame.height - maxH) } else { emptyRemindView.frame = collectionView.bounds } emptyRemindView.emptyData = emptyData } } /// 更新当前播放视频 /// - Returns: <#description#> func updateCurrentPlayMusic(isPlaying: Bool, isClearCurrentMusic: Bool) { if lastIndexPath != nil, itemList.count > (lastIndexPath?.item ?? 0) { (itemList[lastIndexPath?.item ?? 0] as? PQVoiceModel)?.isPlaying = isPlaying collectionView.reloadItems(at: [lastIndexPath!]) } if isClearCurrentMusic { if lastIndexPath != nil, itemList.count > (lastIndexPath?.item ?? 0) { (itemList[lastIndexPath?.item ?? 0] as? PQVoiceModel)?.isSelected = false (itemList[lastIndexPath?.item ?? 0] as? PQVoiceModel)?.isPlaying = false collectionView.reloadItems(at: [lastIndexPath!]) } lastIndexPath = nil } } } // MARK: - 卡点音乐相关代理 /// 卡点音乐相关代理 extension PQStuckPointMusicContentController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UIScrollViewDelegate { func collectionView(_: UICollectionView, numberOfItemsInSection _: Int) -> Int { return itemList.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let itemData: Any = itemList[indexPath.item] if itemData is ([PQStuckPointMusicTagsModel], ([UICollectionViewLayoutAttributes], CGFloat)) { let cell = PQStuckPointMusicTagsCell.stuckPointMusicTagsCell(collectionView: collectionView, indexPath: indexPath) cell.itemData = itemData as! ([PQStuckPointMusicTagsModel], ([UICollectionViewLayoutAttributes], CGFloat)) cell.tagsDidSelectedHandle = { [weak self] indexPath, tagsData in if self?.didSelectedHandle != nil { self?.didSelectedHandle!(true, self?.contentType ?? .catagery, indexPath, tagsData ?? PQStuckPointMusicTagsModel()) } if tagsData != nil { // 点击上报:选择音乐分类下的 TAG PQEventTrackViewModel.baseReportUpload(businessType: .bt_buttonClick, objectType: .ot_click_chooseMusicCategoryTag, pageSource: .sp_stuck_selectSynceedUpMusic, extParams: ["categoryName": tagsData?.tagName ?? "", "categoryId": tagsData?.tagId ?? ""], remindmsg: "卡点视频数据上报-(点击上报:选择音乐分类下的 TAG)") } } return cell } else if itemData is PQEmptyModel { let cell = PQStuckPointSearchEmptyCell.stuckPointSearchEmptyCell(collectionView: collectionView, indexPath: indexPath) cell.bgmData = itemData as? PQEmptyModel return cell } else { let cell = PQStuckPointMusicContentCell.stuckPointMusicContentCell(collectionView: collectionView, indexPath: indexPath) cell.contentType = contentType cell.bgmData = itemList[indexPath.item] if cell.bgmData is PQVoiceModel { let bgmData = cell.bgmData as! PQVoiceModel if bgmData.isSelected { lastIndexPath = indexPath } } cell.btnClickHandle = { [weak self] sender, bgmData in if self?.btnClickHandle != nil { self?.btnClickHandle!(sender, bgmData) } if bgmData is PQVoiceModel { if self?.contentType == .page { // 卡点视频音乐选择音乐素材 PQEventTrackViewModel.baseReportUpload(businessType: .bt_buttonClick, objectType: .ot_click_chooseMusic, pageSource: .sp_stuck_selectSynceedUpMusic, extParams: ["musicName": (bgmData as? PQVoiceModel)?.musicName ?? "", "musicId": (bgmData as? PQVoiceModel)?.musicId ?? ""], remindmsg: "卡点视频数据上报-(点击上报:选择音乐素材)") } else if self?.contentType == .serach { // 点击上报:选择音乐素材 PQEventTrackViewModel.baseReportUpload(businessType: .bt_buttonClick, objectType: .ot_click_chooseSearchMusic, pageSource: .sp_stuck_searchSyncedUpMusic, extParams: ["musicName": (bgmData as? PQVoiceModel)?.musicName ?? "", "musicId": (bgmData as? PQVoiceModel)?.musicId ?? "", "isHotMusic": self?.itemList.first is PQEmptyModel], remindmsg: "卡点视频数据上报-(点击上报:选择音乐素材)") } } } return cell } } func collectionView(_ collectionView: UICollectionView, layout _: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { let itemData: Any = itemList[indexPath.item] if itemData is ([PQStuckPointMusicTagsModel], ([UICollectionViewLayoutAttributes], CGFloat)) { let height: CGFloat = ((itemData as? ([PQStuckPointMusicTagsModel], ([UICollectionViewLayoutAttributes], CGFloat)))?.0.count ?? 0) > 0 ? (((itemData as? ([PQStuckPointMusicTagsModel], ([UICollectionViewLayoutAttributes], CGFloat)))?.1.1 ?? 0) + 35) : 0 return CGSize(width: collectionView.frame.width, height: height) } else if itemData is PQEmptyModel { return CGSize(width: collectionView.frame.width, height: 290) } else { return CGSize(width: collectionView.frame.width, height: cellHight) } } func collectionView(_: UICollectionView, didSelectItemAt indexPath: IndexPath) { if !isNetConnected() { cShowHUB(superView: nil, msg: "请有网时再试") return } if !(itemList[indexPath.item] is PQEmptyModel) { if lastIndexPath != indexPath { if contentType == .catagery { (itemList[lastIndexPath?.item ?? 0] as? PQStuckPointMusicTagsModel)?.isSelected = false (itemList[indexPath.item] as? PQStuckPointMusicTagsModel)?.isSelected = true } else { (itemList[lastIndexPath?.item ?? 0] as? PQVoiceModel)?.isSelected = false (itemList[lastIndexPath?.item ?? 0] as? PQVoiceModel)?.isPlaying = false (itemList[indexPath.item] as? PQVoiceModel)?.isSelected = true (itemList[indexPath.item] as? PQVoiceModel)?.isPlaying = true } if lastIndexPath != nil { collectionView.reloadItems(at: [lastIndexPath!]) } let cell = collectionView.cellForItem(at: indexPath) as? PQStuckPointMusicContentCell cell?.bgmData = itemList[indexPath.item] lastIndexPath = indexPath // collectionView.reloadData() } else if contentType != .catagery { (itemList[indexPath.item] as? PQVoiceModel)?.isPlaying = !((itemList[indexPath.item] as? PQVoiceModel)?.isPlaying ?? false) (itemList[indexPath.item] as? PQVoiceModel)?.isSelected = true let cell = collectionView.cellForItem(at: indexPath) as? PQStuckPointMusicContentCell cell?.bgmData = itemList[indexPath.item] // collectionView.reloadItems(at: [indexPath]) } } if contentType == .catagery { collectionView.scrollToItem(at: indexPath, at: .centeredVertically, animated: true) } if didSelectedHandle != nil { didSelectedHandle!(false, contentType, indexPath, itemList[indexPath.item]) } if itemList[indexPath.item] is PQVoiceModel { if contentType == .page { // 卡点视频音乐素材试听 PQEventTrackViewModel.baseReportUpload(businessType: .bt_buttonClick, objectType: .ot_click_auditionMusic, pageSource: .sp_stuck_selectSynceedUpMusic, extParams: ["musicName": (itemList[indexPath.item] as? PQVoiceModel)?.musicName ?? "", "musicId": (itemList[indexPath.item] as? PQVoiceModel)?.musicId ?? ""], remindmsg: "卡点视频数据上报-(点击上报:音乐素材试听)") } else if contentType == .serach { // 点击上报:试听音乐素材 PQEventTrackViewModel.baseReportUpload(businessType: .bt_buttonClick, objectType: .ot_click_auditionSearchMusic, pageSource: .sp_stuck_searchSyncedUpMusic, extParams: ["musicName": (itemList[indexPath.item] as? PQVoiceModel)?.musicName ?? "", "musicId": (itemList[indexPath.item] as? PQVoiceModel)?.musicId ?? "", "isHotMusic": itemList.first is PQEmptyModel], remindmsg: "卡点视频数据上报-(点击上报:试听音乐素材)") } } else if contentType == .catagery && (itemList[indexPath.item] is PQStuckPointMusicTagsModel) { // 点击上报:选择音乐分类 PQEventTrackViewModel.baseReportUpload(businessType: .bt_buttonClick, objectType: .ot_click_chooseMusicCategory, pageSource: .sp_stuck_selectSynceedUpMusic, extParams: ["categoryName": (itemList[indexPath.item] as? PQStuckPointMusicTagsModel)?.tagName ?? "", "categoryId": (itemList[indexPath.item] as? PQStuckPointMusicTagsModel)?.tagId ?? ""], remindmsg: "卡点视频数据上报-(点击上报:选择音乐分类)") } } func scrollViewDidScroll(_: UIScrollView) { if scroDidScroHandle != nil { scroDidScroHandle!() } } func collectionView(_: UICollectionView, willDisplay _: UICollectionViewCell, forItemAt indexPath: IndexPath) { let itemData: Any = itemList[indexPath.item] if itemData is PQVoiceModel { if contentType == .page { // 卡点视频音乐音乐素材曝光 PQEventTrackViewModel.baseReportUpload(businessType: .bt_buttonView, objectType: .ot_view_syncedUpMusic, pageSource: .sp_stuck_selectSynceedUpMusic, extParams: ["musicName": (itemData as? PQVoiceModel)?.musicName ?? "", "musicId": (itemData as? PQVoiceModel)?.musicId ?? ""], remindmsg: "卡点视频数据上报-(曝光上报:音乐素材曝光)") } else if contentType == .serach { // 曝光上报:搜索结果音乐素材曝光 PQEventTrackViewModel.baseReportUpload(businessType: .bt_buttonView, objectType: .ot_view_searchMusic, pageSource: .sp_stuck_searchSyncedUpMusic, extParams: ["musicName": (itemData as? PQVoiceModel)?.musicName ?? "", "musicId": (itemData as? PQVoiceModel)?.musicId ?? "", "isHotMusic": itemList.first is PQEmptyModel], remindmsg: "卡点视频数据上报-(曝光上报:搜索结果音乐素材曝光)") } } } }