TSThemeBrowseVC.swift 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. //
  2. // TSThemeBrowseVC.swift
  3. // AIRingtone
  4. //
  5. // Created by 100Years on 2025/3/2.
  6. //
  7. private let cellId = "TSThemeBrowseCell"
  8. class TSThemeBrowseVC: TSBaseVC {
  9. var currentIndex:Int{
  10. didSet {
  11. browseViewModel.setFinallyIndex(currentIndex,ringtone:currentModel?.ringtone)
  12. }
  13. }
  14. var themeViewModel:TSThemeVM
  15. var closePage:()->Void
  16. lazy var audioPlayer = TSBusinessAudioPlayer.shared
  17. lazy var browseViewModel: TSThemeBrowseVM = {
  18. browseViewModel = TSThemeBrowseVM()
  19. browseViewModel.audioPlayer = audioPlayer
  20. return browseViewModel
  21. }()
  22. var currentRingtone:String?
  23. var currentModel:TSThemeModel?{
  24. return themeViewModel.listModelArray.safeObj(At: currentIndex)
  25. }
  26. init(currentIndex:Int,themeViewModel: TSThemeVM, closePage: @escaping () -> Void) {
  27. self.currentIndex = currentIndex
  28. self.themeViewModel = themeViewModel
  29. self.closePage = closePage
  30. super.init()
  31. }
  32. @MainActor required init?(coder: NSCoder) {
  33. fatalError("init(coder:) has not been implemented")
  34. }
  35. lazy var btnView: TSTBBtnView = {
  36. let btnView = TSTBBtnView(
  37. targetVC: self,
  38. closePageSelector: #selector(clickClosePage),
  39. copyrightSelector: #selector(clickNavCopyright),
  40. lockSelector:#selector(clickLock),
  41. callSelector: #selector(clickCall),
  42. soundSelector: #selector(clickSound),
  43. doneSelector: #selector(clickDone)
  44. )
  45. return btnView
  46. }()
  47. lazy var callPreview:TSTBCallPreviewView = {
  48. let callPreview = TSTBCallPreviewView()
  49. callPreview.closePage = { [weak self] in
  50. guard let self = self else { return }
  51. btnView.isHidden = false
  52. }
  53. callPreview.isHidden = true
  54. return callPreview
  55. }()
  56. lazy var desktopPreview: TSTBDesktopPreviewView = {
  57. let desktopPreview = TSTBDesktopPreviewView()
  58. desktopPreview.closePage = { [weak self] in
  59. guard let self = self else { return }
  60. btnView.isHidden = false
  61. }
  62. desktopPreview.isHidden = true
  63. return desktopPreview
  64. }()
  65. lazy var collectionView: UICollectionView = {
  66. let layout = UICollectionViewFlowLayout()
  67. layout.scrollDirection = .vertical
  68. layout.minimumInteritemSpacing = 0
  69. layout.minimumLineSpacing = 0
  70. layout.itemSize = CGSize(width: k_ScreenWidth, height: k_ScreenHeight)
  71. let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
  72. collectionView.delegate = self
  73. collectionView.dataSource = self
  74. collectionView.showsVerticalScrollIndicator = false
  75. collectionView.showsHorizontalScrollIndicator = false
  76. collectionView.backgroundColor = .clear
  77. collectionView.scrollsToTop = false
  78. if #available(iOS 11.0, *) {
  79. collectionView.contentInsetAdjustmentBehavior = .never
  80. }
  81. collectionView.register(TSThemeBrowseCell.self, forCellWithReuseIdentifier: cellId)
  82. collectionView.isPagingEnabled = true
  83. collectionView.addLoadMore { [weak self] in
  84. guard let self = self else { return }
  85. themeViewModel.getMoreData { [weak self] success,haveMore in
  86. guard let self = self else { return }
  87. if success {
  88. collectionView.reloadData()
  89. }
  90. collectionView.endRefreshing(noMore: !haveMore)
  91. }
  92. }
  93. return collectionView
  94. }()
  95. override func createView() {
  96. setNavBarViewHidden(true)
  97. contentView.addSubview(collectionView)
  98. collectionView.snp.makeConstraints { make in
  99. make.edges.equalToSuperview()
  100. }
  101. contentView.addSubview(btnView)
  102. btnView.snp.makeConstraints { make in
  103. make.edges.equalToSuperview()
  104. }
  105. contentView.addSubview(callPreview)
  106. callPreview.snp.makeConstraints { make in
  107. make.edges.equalToSuperview()
  108. }
  109. contentView.addSubview(desktopPreview)
  110. desktopPreview.snp.makeConstraints { make in
  111. make.edges.equalToSuperview()
  112. }
  113. }
  114. override func dealThings() {
  115. kDelayMainShort {
  116. self.collectionView.scrollToItem(at: IndexPath(item: self.currentIndex, section: 0), at: .bottom, animated: false)
  117. }
  118. browseViewModel.finallyIndex = currentIndex
  119. browseViewModel.finallyIndexChange = {[weak self] in
  120. guard let self = self else { return }
  121. setVipUI()
  122. }
  123. setVipUI()
  124. NotificationCenter.default.addObserver(forName: .kBusinessAudioStateChange, object: nil, queue: nil) { notification in
  125. if let userInfo = notification.userInfo as? [String: TSBusinessAudioPlayer.PlayerState], let state = userInfo["PlayerState"] {
  126. kExecuteOnMainThread {
  127. self.audioPlayerStateChange(state: state)
  128. }
  129. }
  130. }
  131. }
  132. func setVipUI(){
  133. self.btnView.doneBtnView.setVip(vip: self.getNeedVip)
  134. }
  135. var getNeedVip:Bool{
  136. if let currentModel = self.currentModel {
  137. if currentModel.vip {
  138. return true
  139. }
  140. }
  141. return false
  142. }
  143. }
  144. extension TSThemeBrowseVC {
  145. func audioPlayerStateChange(state:TSBusinessAudioPlayer.PlayerState){
  146. switch state {
  147. case .loading(let progress):
  148. if progress == 0.0 {
  149. btnView.isSoundloadling = true
  150. }else if progress == 1.0 {
  151. btnView.isSoundloadling = false
  152. }
  153. case .volume(let volume):
  154. btnView.soundVolume = volume
  155. case .stop,.play,.pause:
  156. btnView.isSoundloadling = false
  157. default:
  158. break
  159. }
  160. }
  161. func setUpRingtone() {
  162. if let ringtone = currentModel?.ringtone {
  163. TSCommonTool.downloadAndCacheFile(from: ringtone) { path, error in
  164. if let path = path {
  165. self.currentRingtone = path
  166. }else{
  167. self.currentRingtone = nil
  168. }
  169. }
  170. }else{
  171. self.currentRingtone = nil
  172. }
  173. }
  174. override func viewWillDisappear(_ animated: Bool) {
  175. super.viewWillDisappear(animated)
  176. browseViewModel.audioPlayer?.stop()
  177. browseViewModel.audioPlayer?.setVolume(volume: 1.0)
  178. }
  179. override func viewWillAppear(_ animated: Bool) {
  180. super.viewWillAppear(animated)
  181. if browseViewModel.audioPlayer?.playerUsable == true {
  182. browseViewModel.audioPlayer?.setVolume(volume: 1.0)
  183. browseViewModel.audioPlayer?.play()
  184. }else{
  185. browseViewModel.audioPlayer?.playUrlString( currentModel?.ringtone,loop: true)
  186. }
  187. }
  188. }
  189. extension TSThemeBrowseVC {
  190. @objc func clickClosePage(){
  191. self.pop()
  192. self.closePage()
  193. }
  194. @objc func clickNavCopyright(){
  195. navigationController?.pushViewController(TSThemeCopyrightVC(), animated: true)
  196. }
  197. @objc func clickLock(){
  198. btnView.isHidden = true
  199. callPreview.urlString = currentModel?.poster
  200. callPreview.isHidden = false
  201. }
  202. @objc func clickCall(){
  203. btnView.isHidden = true
  204. desktopPreview.urlString = currentModel?.photo
  205. desktopPreview.islandView.nameLab.text = currentModel?.name
  206. desktopPreview.isHidden = false
  207. }
  208. @objc func clickSound(){
  209. let volume = audioPlayer.changeAudioSwitch()
  210. btnView.soundVolume = volume
  211. }
  212. @objc func clickDone(){
  213. if let currentModel = currentModel {
  214. let setVC = TSThemeSetVC(model: currentModel, duration: Float(audioPlayer.duration))
  215. kPushVC(target: self, modelVC: setVC)
  216. }
  217. }
  218. }
  219. //MARK: UICollectionViewDataSource
  220. extension TSThemeBrowseVC:UICollectionViewDataSource,UICollectionViewDelegate {
  221. func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
  222. dePrint("scrollViewDidEndDecelerating")
  223. resetIndexWithOffset(scrollView)
  224. }
  225. func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
  226. dePrint("scrollViewDidEndScrollingAnimation")
  227. resetIndexWithOffset(scrollView)
  228. }
  229. private func resetIndexWithOffset(_ scrollView: UIScrollView) {
  230. let item = Int((scrollView.contentOffset.y / scrollView.bounds.height).rounded())
  231. currentIndex = item
  232. }
  233. func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
  234. return themeViewModel.listModelArray.count
  235. }
  236. func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
  237. let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! TSThemeBrowseCell
  238. if let model = themeViewModel.listModelArray.safeObj(At: indexPath.item){
  239. cell.netWorkImageView.setAsyncImage(urlString: model.poster,placeholder:kPlaceholderImage,contentMode: .scaleAspectFill)
  240. cell.islandView.showImageView.setAsyncImage(urlString: model.photo,placeholder:kPlaceholderImage,contentMode: .scaleAspectFill)
  241. cell.islandView.nameLab.text = model.name
  242. }
  243. return cell
  244. }
  245. }
  246. class TSThemeBrowseCell : TSBaseCollectionCell{
  247. lazy var islandView : TSTSIslandView = {
  248. let islandView = TSTSIslandView()
  249. return islandView
  250. }()
  251. lazy var netWorkImageView : UIImageView = {
  252. let netWorkImageView = UIImageView()
  253. return netWorkImageView
  254. }()
  255. override func creatUI() {
  256. bgContentView.addSubview(netWorkImageView)
  257. netWorkImageView.snp.makeConstraints { make in
  258. make.center.equalToSuperview()
  259. make.width.equalTo(k_ScreenWidth)
  260. make.height.equalTo(kDesignScale*812)
  261. }
  262. bgContentView.addSubview(islandView)
  263. islandView.snp.makeConstraints { make in
  264. make.top.equalTo(k_Nav_Height+10)
  265. make.centerX.equalToSuperview()
  266. make.width.equalTo(islandView.width)
  267. make.height.equalTo(islandView.height)
  268. }
  269. }
  270. }