PQSelecteMusicView.swift 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  1. //
  2. // PQSelecteMusic.swift
  3. // BFFramework
  4. //
  5. // Created by ak on 2021/8/4.
  6. // 功能:显示编辑界面里的音乐选择界面
  7. import Foundation
  8. class PQSelecteMusicView: UIView {
  9. // 所有分类数据
  10. var catageryDatas: [PQStuckPointMusicTagsModel] = Array<PQStuckPointMusicTagsModel>.init()
  11. // 歌单数据
  12. var musicDatas: [PQVoiceModel] = Array<PQVoiceModel>.init()
  13. // 当前页码
  14. var pageNum: Int = 0
  15. // 当前视频使用的音乐数据
  16. var currentPlayingInVideoData : PQVoiceModel?
  17. // 当前试听播放的音乐数据
  18. var currentPlayData: PQVoiceModel?
  19. // 当前播放的音频
  20. var playerItem: AVPlayerItem?
  21. var playerItemHavObserver: Bool = false
  22. // 按钮点击的回调
  23. var btnClickHandle: ((_ sender: UIButton, _ bgmData: Any?) -> Void)?
  24. // 点击播放一个歌,回调
  25. var didSelectItemHandle:((_ statue:voiceStatue) -> Void)?
  26. // 当前选择的分类
  27. var currentSelectTag:PQStuckPointMusicTagsModel?
  28. //搜索出来的歌曲要插入到热门的前面 有可能是多个
  29. var searchMusiceDatas: [PQVoiceModel] = Array<PQVoiceModel>.init()
  30. //第一次进入时自动插入的数据
  31. var firstInsertVoiceModel:PQVoiceModel?
  32. lazy var avPlayer: AVPlayer = {
  33. let avPlayer = AVPlayer()
  34. PQNotification.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: avPlayer.currentItem, queue: .main) { [weak self] notify in
  35. BFLog(message: "AVPlayerItemDidPlayToEndTime = \(notify)")
  36. avPlayer.seek(to: CMTime(value: CMTimeValue((self?.currentPlayData?.startTime ?? 0) * 1000), timescale: CMTimeScale(playerTimescale)))
  37. if(self?.currentPlayData?.voiceStatue == .isPlaying){
  38. self?.currentPlayData?.voiceStatue = .isPause
  39. self?.selectMusicCollection.reloadData()
  40. }
  41. }
  42. // PQNotification.addObserver(forName: .AVPlayerItemNewErrorLogEntry, object: avPlayer.currentItem, queue: .main) { notify in
  43. // BFLog(message: "AVPlayerItemNewErrorLogEntry = \(notify)")
  44. // }
  45. // PQNotification.addObserver(forName: .AVPlayerItemFailedToPlayToEndTime, object: avPlayer.currentItem, queue: .main) { notify in
  46. // BFLog(message: "AVPlayerItemFailedToPlayToEndTime = \(notify)")
  47. // }
  48. // PQNotification.addObserver(forName: .AVPlayerItemPlaybackStalled, object: avPlayer.currentItem, queue: .main) { notify in
  49. // BFLog(message: "AVPlayerItemPlaybackStalled = \(notify)")
  50. // }
  51. // avPlayer.addPeriodicTimeObserver(forInterval: CMTime(value: 1, timescale: CMTimeScale(playerTimescale)), queue: .main) { [weak self] cmTime in
  52. // BFLog(message: "addPeriodicTimeObserver = \(cmTime)")
  53. // }
  54. return avPlayer
  55. }()
  56. // 音乐分类的
  57. lazy var categoryCollection: UICollectionView = {
  58. let flowLayout = UICollectionViewFlowLayout()
  59. flowLayout.sectionInset = UIEdgeInsets.zero
  60. flowLayout.minimumLineSpacing = 0
  61. flowLayout.minimumInteritemSpacing = 0
  62. flowLayout.scrollDirection = .horizontal
  63. let categoryCollection = UICollectionView(frame: .zero, collectionViewLayout: flowLayout)
  64. categoryCollection.showsVerticalScrollIndicator = false
  65. categoryCollection.showsHorizontalScrollIndicator = false
  66. categoryCollection.delegate = self
  67. categoryCollection.dataSource = self
  68. categoryCollection.backgroundColor = .clear
  69. categoryCollection.register(PQSelectMusicTagsCell.self, forCellWithReuseIdentifier: "PQSelectMusicTagsCell")
  70. categoryCollection.delaysContentTouches = false
  71. return categoryCollection
  72. }()
  73. // 每一个分类下所有歌曲
  74. lazy var selectMusicCollection: UICollectionView = {
  75. let flowLayout = UICollectionViewFlowLayout()
  76. flowLayout.sectionInset = UIEdgeInsets.zero
  77. flowLayout.minimumLineSpacing = 0
  78. flowLayout.minimumInteritemSpacing = 0
  79. flowLayout.scrollDirection = .horizontal
  80. let selectMusicCollection = UICollectionView(frame: .zero, collectionViewLayout: flowLayout)
  81. selectMusicCollection.showsVerticalScrollIndicator = false
  82. selectMusicCollection.showsHorizontalScrollIndicator = false
  83. selectMusicCollection.delegate = self
  84. selectMusicCollection.dataSource = self
  85. selectMusicCollection.backgroundColor = .clear
  86. selectMusicCollection.register(PQSelectMusicCell.self, forCellWithReuseIdentifier: String(describing: PQSelectMusicCell.self))
  87. selectMusicCollection.delaysContentTouches = false
  88. selectMusicCollection.contentInset = UIEdgeInsets(top: 0, left: 17, bottom: 0, right: 0)
  89. return selectMusicCollection
  90. }()
  91. // 搜索音乐btn
  92. lazy var musicSearchBtn: UIButton = {
  93. let musicSearchBtn = UIButton(type: .custom)
  94. musicSearchBtn.setTitle("搜索", for: .normal)
  95. musicSearchBtn.setImage(UIImage().BF_Image(named: "musicSearch"), for: .normal)
  96. musicSearchBtn.setTitleColor(UIColor.hexColor(hexadecimal: "#959595"), for: .normal)
  97. musicSearchBtn.titleLabel?.font = UIFont.systemFont(ofSize: 14)
  98. return musicSearchBtn
  99. }()
  100. deinit {
  101. PQNotification.removeObserver(self)
  102. PQNotification.removeObserver(self.avPlayer.currentItem as Any)
  103. if playerItemHavObserver {
  104. avPlayer.currentItem?.removeObserver(self, forKeyPath: "status")
  105. avPlayer.currentItem?.removeObserver(self, forKeyPath: "error")
  106. }
  107. avPlayer.pause()
  108. avPlayer.replaceCurrentItem(with: nil)
  109. playerItem = nil
  110. }
  111. override init(frame: CGRect) {
  112. super.init(frame: frame)
  113. addSubview(categoryCollection)
  114. addSubview(selectMusicCollection)
  115. addSubview(musicSearchBtn)
  116. }
  117. func showData(){
  118. autolayout()
  119. isHidden = false
  120. //不是每一次点击都显示数据
  121. if(musicDatas.count == 0){
  122. loadRequestTagsList()
  123. }
  124. }
  125. required init?(coder _: NSCoder) {
  126. fatalError("init(coder:) has not been implemented")
  127. }
  128. //插入数据
  129. func insertSearchMusic(model:PQVoiceModel) {
  130. for oldModel in musicDatas {
  131. oldModel.voiceStatue = .isNormal
  132. }
  133. let musicIndex = musicDatas.firstIndex(where: { (music) -> Bool in
  134. (music.musicId == model.musicId)
  135. })
  136. if(musicIndex == nil){
  137. model.voiceStatue = .isSelected
  138. searchMusiceDatas.insert(model, at: 0)
  139. //有搜索的数据
  140. if(currentSelectTag?.tagId == 425){
  141. musicDatas.insert(model, at: 0)
  142. }
  143. }else{
  144. let selectMusicData = musicDatas[musicIndex!]
  145. selectMusicData.voiceStatue = .isSelected
  146. musicDatas.remove(at: musicIndex!)
  147. musicDatas.insert(selectMusicData, at: 0)
  148. }
  149. self.currentPlayingInVideoData = model
  150. selectMusicCollection.reloadData()
  151. //划动到选择的音乐位置
  152. selectMusicCollection.scrollToItem(at: IndexPath(row: 0, section: 0), at: .centeredHorizontally, animated: true)
  153. }
  154. func autolayout() {
  155. categoryCollection.snp_removeConstraints()
  156. selectMusicCollection.snp_removeConstraints()
  157. musicSearchBtn.snp_removeConstraints()
  158. categoryCollection.snp.makeConstraints { make in
  159. make.height.equalTo(20)
  160. make.left.equalToSuperview().offset(91)
  161. make.right.equalToSuperview()
  162. make.top.equalToSuperview().offset(14)
  163. }
  164. selectMusicCollection.snp.makeConstraints { make in
  165. make.height.equalTo(131)
  166. make.left.equalToSuperview()
  167. make.right.equalToSuperview()
  168. make.top.equalToSuperview().offset(54)
  169. }
  170. musicSearchBtn.snp.makeConstraints { make in
  171. make.left.equalToSuperview().offset(12)
  172. make.top.equalToSuperview().offset(14)
  173. make.height.equalTo(20)
  174. make.width.equalTo(60)
  175. }
  176. musicSearchBtn.imagePosition(at: .left, space: 8)
  177. }
  178. /// 请求标签数据
  179. /// - Returns: <#description#>
  180. func loadRequestTagsList() {
  181. PQStuckPointViewModel.stuckPointMusicCategoryList { [weak self] tags, _, _ in
  182. if tags.count > 0 {
  183. // 请求列表数据
  184. self?.requestPageListData(isRefresh: true, tagId: tags.first?.tagId ?? 0)
  185. self?.catageryDatas = tags
  186. self?.currentSelectTag = tags[0]
  187. self?.categoryCollection.reloadData()
  188. }
  189. }
  190. }
  191. /// 请求指定分类的歌列表数据
  192. /// - Returns:
  193. func requestPageListData(isRefresh: Bool = true, isHotPage _: Bool = false, tagId: Int64) {
  194. if isRefresh {
  195. pageNum = 1
  196. musicDatas = []
  197. }
  198. PQStuckPointViewModel.stuckPointMusicPageList(tagId: tagId, pageNum: pageNum, videoCount: 0, imageCount: 0, totalDuration: 0,oldDataMusic: musicDatas) { [weak self] musicInfo, _ in
  199. BFLog(message: "请求音乐列表 pageNum\(String(describing: self?.pageNum)) tagId \(tagId) 返回条数\(musicInfo.count)")
  200. if musicInfo.count > 0 {
  201. self?.pageNum = (self?.pageNum ?? 0) + 1
  202. self?.musicDatas = self!.musicDatas + musicInfo
  203. //有搜索的数据
  204. if((self?.searchMusiceDatas.count ?? 0) > 0 && self!.musicDatas.first?.cacheTagID == 425 && self?.pageNum == 2){
  205. self?.musicDatas.insert(contentsOf: self?.searchMusiceDatas ?? Array.init(), at: 0)
  206. }
  207. if(self?.musicDatas.count ?? 0 > 0){
  208. self?.selectMusicCollection.reloadData()
  209. }else{
  210. BFLog(message: "分类歌曲数据为空!!!!")
  211. }
  212. if( self?.pageNum == 2){
  213. //歌曲列表返回到头部
  214. self?.selectMusicCollection.setContentOffset(.zero, animated: false)
  215. //第一次进入插入的歌曲,插入后置空 如果 不存在只插入一次 防止重
  216. if(self?.firstInsertVoiceModel != nil){
  217. self?.insertSearchMusic(model: (self?.firstInsertVoiceModel)!)
  218. self?.currentPlayingInVideoData = self?.firstInsertVoiceModel
  219. self?.firstInsertVoiceModel = nil
  220. }
  221. }
  222. }
  223. }
  224. }
  225. /// 播放音乐
  226. /// - Parameter itemData: <#itemData description#>
  227. func playStuckPointMusic(itemData: PQVoiceModel?, isClearCurrentMusic: Bool = false) {
  228. if itemData != nil, currentPlayData != itemData {
  229. if !isValidURL(url: itemData?.musicPath ?? "") {
  230. cShowHUB(superView: nil, msg: "本歌曲暂无伴奏版本哦~")
  231. return
  232. }
  233. avPlayer.pause()
  234. if playerItemHavObserver {
  235. playerItem?.removeObserver(self, forKeyPath: "status")
  236. playerItem?.removeObserver(self, forKeyPath: "error")
  237. playerItemHavObserver = false
  238. }
  239. if itemData!.musicId == currentPlayingInVideoData?.musicId {
  240. itemData?.voiceStatue = .isSelected
  241. currentPlayData = itemData
  242. playerItem = nil
  243. return
  244. }
  245. playerItem = AVPlayerItem(url: URL(string: itemData?.musicPath ?? "")!)
  246. if (itemData?.endTime ?? 0) > 0, (itemData?.endTime ?? 0) > (itemData?.startTime ?? 0) {
  247. playerItem?.forwardPlaybackEndTime = CMTime(value: CMTimeValue((itemData?.endTime ?? 0) * playerTimescale), timescale: CMTimeScale(playerTimescale))
  248. }
  249. avPlayer.replaceCurrentItem(with: playerItem)
  250. playerItem?.addObserver(self, forKeyPath: "status", options: .new, context: nil)
  251. playerItem?.addObserver(self, forKeyPath: "error", options: .new, context: nil)
  252. playerItemHavObserver = true
  253. avPlayer.seek(to: CMTime(value: CMTimeValue((itemData?.startTime ?? 0) * playerTimescale), timescale: CMTimeScale(playerTimescale)))
  254. avPlayer.play()
  255. itemData?.voiceStatue = .isPlaying
  256. currentPlayData = itemData
  257. } else if itemData != nil, avPlayer.rate == 0.0 {
  258. if itemData?.musicId != currentPlayingInVideoData?.musicId {
  259. avPlayer.play()
  260. itemData?.voiceStatue = .isPlaying
  261. }
  262. } else {
  263. avPlayer.pause()
  264. itemData?.voiceStatue = .isPause
  265. }
  266. if isClearCurrentMusic {
  267. avPlayer.pause()
  268. currentPlayData = nil
  269. }
  270. }
  271. //暂停播放音乐 并刷新 UI
  272. func pausePlayer() {
  273. avPlayer.pause()
  274. if(currentPlayData?.voiceStatue == .isPlaying){
  275. currentPlayData?.voiceStatue = .isPause
  276. selectMusicCollection.reloadData()
  277. }
  278. }
  279. }
  280. extension PQSelecteMusicView {
  281. override func observeValue(forKeyPath keyPath: String?, of object: Any?, change _: [NSKeyValueChangeKey: Any]?, context _: UnsafeMutableRawPointer?) {
  282. if object is AVPlayerItem, keyPath == "status" {
  283. BFLog(message: "AVPlayerItem - status = \((object as! AVPlayerItem).status.rawValue)")
  284. switch (object as! AVPlayerItem).status {
  285. case .unknown:
  286. break
  287. case .readyToPlay:
  288. break
  289. case .failed:
  290. break
  291. default:
  292. break
  293. }
  294. } else if object is AVPlayerItem, keyPath == "error" {
  295. BFLog(message: "AVPlayerItem - error = \(String(describing: (object as! AVPlayerItem).error))")
  296. }
  297. }
  298. }
  299. /// 卡点音乐相关代理
  300. extension PQSelecteMusicView: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UIScrollViewDelegate {
  301. func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection _: Int) -> Int {
  302. if collectionView == selectMusicCollection {
  303. return musicDatas.count
  304. }
  305. return catageryDatas.count
  306. }
  307. func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
  308. if collectionView == selectMusicCollection {
  309. let itemData: Any = musicDatas[indexPath.item]
  310. let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: PQSelectMusicCell.self), for: indexPath) as! PQSelectMusicCell
  311. if (currentPlayingInVideoData?.musicId != nil && currentPlayingInVideoData?.musicId == (itemData as? PQVoiceModel)?.musicId){
  312. (itemData as? PQVoiceModel)?.voiceStatue = .isSelected
  313. }
  314. cell.bgmData = itemData as? PQVoiceModel
  315. cell.btnClickHandle = { [weak self] sender, bgmData in
  316. //暂停播放音乐
  317. self?.pausePlayer()
  318. self?.currentPlayingInVideoData?.voiceStatue = .isNormal
  319. self?.currentPlayingInVideoData = bgmData as? PQVoiceModel
  320. PQEventTrackViewModel.baseReportUpload(businessType: .bt_buttonClick, objectType: .ot_shanyinApp_musicVideoPreview_musicSelect, pageSource: .sp_shanyinApp_main, extParams: ["musicName":(bgmData as? PQVoiceModel)?.musicName ?? "" ,"musicId":(bgmData as? PQVoiceModel)?.musicId ?? ""], remindmsg: "")
  321. if self?.btnClickHandle != nil {
  322. self?.btnClickHandle!(sender, bgmData)
  323. }
  324. //恢复原来状态
  325. if(self?.musicDatas.count != 0){
  326. for oldModel in self!.musicDatas {
  327. oldModel.voiceStatue = .isNormal
  328. }
  329. }
  330. let musicIndex = self?.musicDatas.firstIndex(where: { (music) -> Bool in
  331. (music.musicId == (bgmData as? PQVoiceModel)?.musicId)
  332. })
  333. self?.musicDatas[musicIndex ?? 0].voiceStatue = .isSelected
  334. self?.selectMusicCollection.reloadData()
  335. }
  336. //自动请求下一页数据
  337. if(indexPath.row == musicDatas.count - 5){
  338. // 请求这个分类的歌单
  339. requestPageListData(isRefresh: false, tagId: currentSelectTag?.tagId ?? 0)
  340. }
  341. return cell
  342. }
  343. let itemData: Any = catageryDatas[indexPath.item]
  344. let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: PQSelectMusicTagsCell.self), for: indexPath) as! PQSelectMusicTagsCell
  345. cell.tagData = itemData as? PQStuckPointMusicTagsModel
  346. return cell
  347. }
  348. func collectionView(_ collectionView: UICollectionView, layout _: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
  349. if collectionView == selectMusicCollection {
  350. return CGSize(width: 60 + 20, height: 131)
  351. }
  352. // 音乐分类要根据文字自适应宽度
  353. let textSize = sizeWithText(text: catageryDatas[indexPath.item].tagName ?? "", font: UIFont.systemFont(ofSize: 14, weight: .regular), size: CGSize(width: CGFloat.greatestFiniteMagnitude, height: 20.0))
  354. return CGSize(width: textSize.width + 26, height: collectionView.frame.height)
  355. }
  356. func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
  357. //歌曲列表
  358. if (collectionView == selectMusicCollection ){
  359. musicDatas.forEach { item in
  360. item.voiceStatue = .isNormal
  361. }
  362. let music = musicDatas[indexPath.item]
  363. music.voiceStatue = .isSelected
  364. // if music.musicId != currentPlayingInVideoData?.musicId{
  365. playStuckPointMusic(itemData:music)
  366. // }else{
  367. // avPlayer.pause()
  368. // }
  369. PQEventTrackViewModel.baseReportUpload(businessType: .bt_buttonClick, objectType: .ot_shanyinApp_musicVideoPreview_musicCategorySelect, pageSource: .sp_shanyinApp_main, extParams: ["categoryName":currentSelectTag?.tagName ?? "","categoryId":currentSelectTag?.tagId ?? ""], remindmsg: "")
  370. // if music.musicId != currentPlayingInVideoData?.musicId{
  371. // BFLog(1, message: "预览:\(music.musicName) 当前:\(currentPlayingInVideoData?.musicName)")
  372. // }
  373. if didSelectItemHandle != nil {
  374. didSelectItemHandle!(music.voiceStatue)
  375. }
  376. selectMusicCollection.reloadData()
  377. }else{
  378. //停止分类列表的滑动。防止切换分类时 crash
  379. selectMusicCollection.setContentOffset(selectMusicCollection.contentOffset , animated: false)
  380. if !isNetConnected() {
  381. cShowHUB(superView: nil, msg: "请有网时再试")
  382. return
  383. }
  384. catageryDatas.forEach { item in
  385. item.isSelected = false
  386. }
  387. catageryDatas[indexPath.item].isSelected = true
  388. categoryCollection.reloadData()
  389. currentSelectTag = catageryDatas[indexPath.item]
  390. // 请求这个分类的歌单
  391. requestPageListData(isRefresh: true, tagId: currentSelectTag?.tagId ?? 0)
  392. }
  393. }
  394. func collectionView(_ collectionView: UICollectionView, willDisplay _: UICollectionViewCell, forItemAt indexPath: IndexPath) {
  395. if (collectionView == selectMusicCollection && musicDatas.count > indexPath.item ){
  396. let music = musicDatas[indexPath.item]
  397. PQEventTrackViewModel.baseReportUpload(businessType: .bt_buttonView, objectType: .ot_shanyinApp_musicVideoPreview_musicView, pageSource: .sp_shanyinApp_main, extParams: ["musicName":music.musicName ?? "" ,"musicId":music.musicId ?? ""], remindmsg: "")
  398. }
  399. }
  400. }
  401. // 分类 cell
  402. class PQSelectMusicTagsCell: UICollectionViewCell {
  403. lazy var titleLab: UILabel = {
  404. let titleLab = UILabel()
  405. titleLab.font = UIFont.systemFont(ofSize: 14)
  406. titleLab.textColor = UIColor.hexColor(hexadecimal: "#959595")
  407. titleLab.textAlignment = .center
  408. titleLab.backgroundColor = PQBFConfig.shared.styleBackGroundColor
  409. return titleLab
  410. }()
  411. override init(frame: CGRect) {
  412. super.init(frame: frame)
  413. contentView.addSubview(titleLab)
  414. }
  415. required init?(coder _: NSCoder) {
  416. fatalError("init(coder:) has not been implemented")
  417. }
  418. var tagData: PQStuckPointMusicTagsModel? {
  419. didSet {
  420. addData()
  421. addLayout()
  422. }
  423. }
  424. func addData() {
  425. titleLab.text = "\(tagData?.tagName ?? "")"
  426. if tagData?.isSelected ?? false {
  427. titleLab.textColor = UIColor.hexColor(hexadecimal: PQBFConfig.shared.styleColor.rawValue)
  428. titleLab.font = UIFont.boldSystemFont(ofSize: 14)
  429. } else {
  430. titleLab.textColor = UIColor.hexColor(hexadecimal: "#959595")
  431. titleLab.font = UIFont.systemFont(ofSize: 14)
  432. }
  433. }
  434. func addLayout() {
  435. titleLab.snp.makeConstraints { make in
  436. make.size.equalToSuperview()
  437. make.left.top.equalToSuperview()
  438. }
  439. }
  440. }
  441. // 歌曲cell PQSelectMusicCell
  442. class PQSelectMusicCell: UICollectionViewCell {
  443. // 按钮点击的回调
  444. var btnClickHandle: ((_ sender: UIButton, _ bgmData: Any?) -> Void)?
  445. var contentType: stuckPointMusicContentType = .catagery
  446. lazy var audioImageView: UIImageView = {
  447. let audioImageView = UIImageView(image: UIImage().BF_Image(named: "videomk_music_default"))
  448. audioImageView.addCorner(corner: 4)
  449. audioImageView.contentMode = .scaleAspectFill
  450. return audioImageView
  451. }()
  452. lazy var imageMaskView: UIView = {
  453. let imageMaskView = UIView()
  454. imageMaskView.backgroundColor = UIColor.hexColor(hexadecimal: PQBFConfig.shared.styleColor.rawValue,alpha: 0.76)
  455. imageMaskView.addCorner(corner: 4)
  456. return imageMaskView
  457. }()
  458. lazy var playImageView: UIImageView = {
  459. let playImageView = UIImageView()
  460. playImageView.image = UIImage().BF_Image(named: "stuckPoint_music_pause")
  461. playImageView.contentMode = .scaleAspectFit
  462. return playImageView
  463. }()
  464. lazy var titleLab: UILabel = {
  465. let titleLab = UILabel()
  466. titleLab.font = UIFont.systemFont(ofSize: 14)
  467. titleLab.textColor = PQBFConfig.shared.styleTitleColor
  468. return titleLab
  469. }()
  470. /// 音乐歌曲名称
  471. lazy var musicNameLab: UILabel = {
  472. let musicNameLab = UILabel()
  473. musicNameLab.textColor = UIColor.hexColor(hexadecimal: "#959595")
  474. musicNameLab.font = UIFont.systemFont(ofSize: 12)
  475. musicNameLab.textAlignment = .center
  476. musicNameLab.lineBreakMode = .byTruncatingTail
  477. musicNameLab.numberOfLines = 2
  478. return musicNameLab
  479. }()
  480. // 使用按钮
  481. lazy var confirmBtn: UIButton = {
  482. let confirmBtn = UIButton(type: .custom)
  483. confirmBtn.setTitle("使用", for: .normal)
  484. confirmBtn.setTitleColor(UIColor.white, for: .normal)
  485. confirmBtn.titleLabel?.font = UIFont.systemFont(ofSize: 14, weight: .medium)
  486. confirmBtn.addTarget(self, action: #selector(confirmClick(sender:)), for: .touchUpInside)
  487. confirmBtn.addCorner(corner: 4)
  488. confirmBtn.backgroundColor = UIColor.hexColor(hexadecimal: PQBFConfig.shared.styleColor.rawValue)
  489. return confirmBtn
  490. }()
  491. lazy var remindView: UIView = {
  492. let remindView = UIView()
  493. remindView.backgroundColor = UIColor.hexColor(hexadecimal: PQBFConfig.shared.styleColor.rawValue)
  494. remindView.addCorner(corner: 3)
  495. return remindView
  496. }()
  497. @objc class func stuckPointMusicContentCell(collectionView: UICollectionView, indexPath: IndexPath) -> PQStuckPointMusicContentCell {
  498. let cell: PQStuckPointMusicContentCell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: PQStuckPointMusicContentCell.self), for: indexPath) as! PQStuckPointMusicContentCell
  499. return cell
  500. }
  501. override init(frame: CGRect) {
  502. super.init(frame: frame)
  503. contentView.addSubview(audioImageView)
  504. audioImageView.addSubview(imageMaskView)
  505. audioImageView.addSubview(playImageView)
  506. contentView.addSubview(titleLab)
  507. contentView.addSubview(musicNameLab)
  508. contentView.addSubview(remindView)
  509. contentView.addSubview(confirmBtn)
  510. }
  511. required init?(coder _: NSCoder) {
  512. fatalError("init(coder:) has not been implemented")
  513. }
  514. var bgmData: PQVoiceModel? {
  515. didSet {
  516. addData()
  517. addLayout()
  518. }
  519. }
  520. func addData() {
  521. audioImageView.setNetImage(url: "\(bgmData?.avatarUrl ?? "")", placeholder: UIImage().BF_Image(named: "videomk_music_default"))
  522. if((bgmData?.musicName ?? "").count <= 4){
  523. musicNameLab.text = (bgmData?.musicName ?? "").appending("\n ")
  524. }else{
  525. musicNameLab.text = (bgmData?.musicName ?? "")
  526. }
  527. if bgmData?.voiceStatue == .isSelected{
  528. playImageView.isHidden = false
  529. imageMaskView.isHidden = false
  530. playImageView.image = UIImage().BF_Image(named: "stuckPoint_music_selected")
  531. } else if bgmData?.voiceStatue == .isPlaying{
  532. playImageView.isHidden = false
  533. imageMaskView.isHidden = false
  534. playImageView.image = nil
  535. playImageView.kf.setImage(with: URL(fileURLWithPath: Bundle().BF_mainbundle().path(forResource: "stuckPoint_music_playing", ofType: ".gif")!))
  536. } else if bgmData?.voiceStatue == .isPause{
  537. playImageView.isHidden = false
  538. imageMaskView.isHidden = false
  539. playImageView.image = UIImage().BF_Image(named: "stuckPoint_music_pause")
  540. }else {
  541. playImageView.isHidden = true
  542. playImageView.image = nil
  543. imageMaskView.isHidden = true
  544. }
  545. // if bgmData?.voiceStatue == .isSelected{
  546. // playImageView.isHidden = false
  547. // imageMaskView.isHidden = false
  548. // if bgmData?.voiceStatue == .isPlaying {
  549. // playImageView.image = nil
  550. // playImageView.kf.setImage(with: URL(fileURLWithPath: Bundle().BF_mainbundle().path(forResource: "stuckPoint_music_playing", ofType: ".gif")!))
  551. //
  552. // } else {
  553. // playImageView.image = UIImage().BF_Image(named: "stuckPoint_music_pause")
  554. // }
  555. //
  556. // } else {
  557. // playImageView.isHidden = true
  558. // playImageView.image = nil
  559. //
  560. // imageMaskView.isHidden = true
  561. // }
  562. confirmBtn.isHidden = !(bgmData?.voiceStatue == .isPause || bgmData?.voiceStatue == .isPlaying)
  563. if(bgmData?.voiceStatue == .isSelected || bgmData?.voiceStatue == .isPause || bgmData?.voiceStatue == .isPlaying){
  564. musicNameLab.textColor = UIColor.hexColor(hexadecimal: PQBFConfig.shared.styleColor.rawValue)
  565. musicNameLab.font = UIFont.boldSystemFont(ofSize: 12)
  566. }else{
  567. musicNameLab.textColor = UIColor.hexColor(hexadecimal: "#959595")
  568. musicNameLab.font = UIFont.systemFont(ofSize: 12)
  569. }
  570. }
  571. func addLayout() {
  572. audioImageView.snp.remakeConstraints { make in
  573. make.left.top.equalToSuperview()
  574. make.width.height.equalTo(60)
  575. }
  576. imageMaskView.snp.makeConstraints { make in
  577. make.size.equalTo(audioImageView)
  578. }
  579. playImageView.snp.remakeConstraints { make in
  580. make.center.equalToSuperview()
  581. make.width.height.equalTo(24)
  582. }
  583. musicNameLab.snp.remakeConstraints { make in
  584. make.width.equalTo(60)
  585. make.height.equalTo(30)
  586. make.top.equalTo(audioImageView.snp_bottom).offset(6)
  587. }
  588. confirmBtn.snp.remakeConstraints { make in
  589. make.width.equalTo(54)
  590. make.height.equalTo(29)
  591. make.top.equalTo(musicNameLab.snp_bottom).offset(6)
  592. make.centerX.equalTo(audioImageView.snp_centerX)
  593. }
  594. audioImageView.addCorner(corner: 60 / 2)
  595. imageMaskView.addCorner(corner: 60 / 2)
  596. }
  597. @objc func confirmClick(sender: UIButton) {
  598. if btnClickHandle != nil {
  599. btnClickHandle!(confirmBtn, bgmData)
  600. }
  601. }
  602. }