TSTabBarController.swift 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. //
  2. // TSTabBarController.swift
  3. // TSLiveWallpaper
  4. //
  5. // Created by 100Years on 2024/12/20.
  6. //
  7. import TSVideoKit
  8. import UIKit
  9. class TSTabBarController: UITabBarController {
  10. lazy var miniBar: PlayMiniBar = PlayMiniBar()
  11. lazy var playerVc: PlayDetailViewController = .init()
  12. lazy var multiSelectView: CWMutiSelectOpeateView = {
  13. let mView = CWMutiSelectOpeateView()
  14. mView.isHidden = true
  15. mView.deleteButton.addTarget(self, action: #selector(deleteButtonAction), for: .touchUpInside)
  16. mView.addPlaylist.addTarget(self, action: #selector(addToPlaylistAction), for: .touchUpInside)
  17. return mView
  18. }()
  19. private var viewControllerArray: [String] = []
  20. private var titleArray: [String] = []
  21. private var selectedImageArray: [String] = []
  22. private var unselectedImageArray: [String] = []
  23. private let markWidth = k_ScreenWidth / 4
  24. private lazy var markView: UIView = {
  25. let bgView = UIView()
  26. let imageView = UIImageView.createImageView(imageName: "tabbar_select_mark")
  27. bgView.addSubview(imageView)
  28. imageView.snp.makeConstraints { make in
  29. make.top.centerX.equalToSuperview()
  30. make.width.equalTo(24)
  31. make.height.equalTo(8)
  32. }
  33. return bgView
  34. }()
  35. override func viewDidLoad() {
  36. super.viewDidLoad()
  37. delegate = self
  38. createUI()
  39. setUpData()
  40. initExampleData()
  41. }
  42. @objc private func setUpData() {
  43. viewControllerArray = ["MusicContainerViewController", "TSHomeVC", "TSRandomWallpaperVC", "TSMineVC"]
  44. selectedImageArray = [
  45. "tabbar_select_music",
  46. "tabbar_select_home",
  47. "tabbar_select_random",
  48. "tabbar_select_mine",
  49. ]
  50. unselectedImageArray = [
  51. "tabbar_unSelect_music",
  52. "tabbar_unSelect_home",
  53. "tabbar_unSelect_random",
  54. "tabbar_unSelect_mine",
  55. ]
  56. var tabArray: [UINavigationController] = []
  57. for i in 0 ..< viewControllerArray.count {
  58. if let rootViewController = viewControllerArray[i].toInstance(of: UIViewController.self) {
  59. let nav = TSBaseNavigationC(rootViewController: rootViewController)
  60. nav.view.backgroundColor = UIColor.black
  61. nav.tabBarItem = tabBarItem(
  62. title: "titleArray[i].localized",
  63. image: UIImage(named: unselectedImageArray[i]),
  64. selectedImage: UIImage(named: selectedImageArray[i]),
  65. tag: i
  66. )
  67. tabArray.append(nav)
  68. }
  69. }
  70. viewControllers = tabArray
  71. }
  72. private func createUI() {
  73. tabBar.barStyle = .black
  74. tabBar.isTranslucent = true
  75. if #available(iOS 13.0, *) {
  76. let appearance = UITabBarAppearance()
  77. appearance.backgroundEffect = UIBlurEffect(style: .dark) // 使用高斯模糊
  78. tabBar.standardAppearance = appearance
  79. if #available(iOS 15.0, *) {
  80. tabBar.scrollEdgeAppearance = appearance // 针对滚动边缘的外观
  81. }
  82. }
  83. tabBar.addSubview(markView)
  84. markView.snp.makeConstraints { make in
  85. make.top.equalTo(0)
  86. make.left.equalTo(0)
  87. make.width.equalTo(markWidth)
  88. make.height.equalTo(8)
  89. }
  90. addMusicAndMiniBar()
  91. }
  92. func updateMarkViewFrame() {
  93. markView.snp.updateConstraints { make in
  94. make.left.equalTo(CGFloat(selectedIndex) * markWidth)
  95. }
  96. }
  97. private func tabBarItem(title: String, image: UIImage?, selectedImage: UIImage?, tag: Int) -> UITabBarItem {
  98. let tabBarItem = UITabBarItem()
  99. tabBarItem.image = image?.withRenderingMode(.alwaysOriginal)
  100. tabBarItem.selectedImage = selectedImage?.withRenderingMode(.alwaysOriginal)
  101. tabBarItem.imageInsets = UIEdgeInsets(top: 0, left: 0, bottom: -8, right: 0) // 向下移动图标
  102. return tabBarItem
  103. }
  104. var currentNav: UINavigationController? {
  105. if selectedIndex < (viewControllers?.count ?? 0) {
  106. return viewControllers?[selectedIndex] as? UINavigationController
  107. }
  108. return nil
  109. }
  110. deinit {
  111. debugPrint("TSTabBarController deinit")
  112. NotificationCenter.default.removeObserver(self)
  113. }
  114. func initExampleData() {
  115. if UserDefaults.standard.string(forKey: "InitExampleData") == nil {
  116. if let path = Bundle.main.path(forResource: "Example Music", ofType: ".mp3") {
  117. let fileUrl = URL(fileURLWithPath: path)
  118. ExampleIniter.default.copyFileToUrl(url: fileUrl)
  119. UserDefaults.standard.set("1", forKey: "InitExampleData")
  120. }
  121. DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
  122. if let firstVideo = TSVideoOperator.shared.dataManager.fetchAllVideos().first {
  123. TSVideoOperator.shared.playerViewModel.currentVideo = firstVideo
  124. PlayerManager.shared.miniBar.updateVideoInfo(video: firstVideo, state: .pause)
  125. }
  126. }
  127. }
  128. }
  129. }
  130. extension TSTabBarController: UITabBarControllerDelegate {
  131. func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
  132. updateMarkViewFrame()
  133. }
  134. }
  135. // MARK: 音乐布局相关
  136. extension TSTabBarController {
  137. private func addMusicAndMiniBar() {
  138. let tap = UITapGestureRecognizer(target: self, action: #selector(showPlayDetailVc))
  139. miniBar.bgImageView.addGestureRecognizer(tap)
  140. miniBar.layer.cornerRadius = 16
  141. miniBar.layer.masksToBounds = true
  142. view.addSubview(miniBar)
  143. view.addSubview(playerVc.view)
  144. view.addSubview(multiSelectView)
  145. view.bringSubviewToFront(multiSelectView)
  146. makeMusicConstraints()
  147. }
  148. private func makeMusicConstraints() {
  149. miniBar.snp.makeConstraints { make in
  150. make.bottom.equalToSuperview().offset(-UIDevice.tabBarHeight)
  151. make.leading.equalToSuperview().offset(10)
  152. make.trailing.equalToSuperview().offset(-10)
  153. make.height.equalTo(62)
  154. }
  155. playerVc.view.snp.makeConstraints { make in
  156. make.top.equalTo(view.snp.bottom)
  157. make.leading.trailing.equalToSuperview()
  158. make.height.equalTo(UIScreen.kScreenHeight)
  159. }
  160. multiSelectView.snp.makeConstraints { make in
  161. make.bottom.equalToSuperview()
  162. make.leading.trailing.equalToSuperview()
  163. make.height.equalTo(k_Height_TabBar + 62)
  164. }
  165. }
  166. func moveDownMiniBar() {
  167. miniBar.snp.remakeConstraints { make in
  168. make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom)
  169. make.leading.equalToSuperview().offset(10)
  170. make.trailing.equalToSuperview().offset(-10)
  171. make.height.equalTo(62)
  172. }
  173. }
  174. func moveUpMiniBar() {
  175. miniBar.snp.remakeConstraints { make in
  176. make.bottom.equalToSuperview().offset(-UIDevice.tabBarHeight)
  177. make.leading.equalToSuperview().offset(10)
  178. make.trailing.equalToSuperview().offset(-10)
  179. make.height.equalTo(62)
  180. }
  181. }
  182. }
  183. // MARK: 音乐操作相关
  184. extension TSTabBarController {
  185. func showMultiSelectView() {
  186. multiSelectView.isHidden = false
  187. view.bringSubviewToFront(multiSelectView)
  188. }
  189. func hideMultiSelectView() {
  190. multiSelectView.isHidden = true
  191. view.bringSubviewToFront(multiSelectView)
  192. }
  193. @objc func deleteButtonAction() {
  194. PlayerManager.shared.deleteSelectedVideos()
  195. }
  196. @objc func addToPlaylistAction() {
  197. PlayerManager.shared.addVideosToPlaylist()
  198. }
  199. @objc func showPlayDetailVc() {
  200. showPlayerVc()
  201. }
  202. func showPlayerVc() {
  203. // ADManager.shared.prepareAd(scenes: [ADScene.downloadReward])
  204. UIView.animate(withDuration: 0.2) {
  205. self.playerVc.view.snp.remakeConstraints { make in
  206. make.top.equalToSuperview()
  207. make.leading.trailing.equalToSuperview()
  208. make.height.equalTo(UIScreen.kScreenHeight)
  209. }
  210. self.view.setNeedsLayout()
  211. self.view.layoutIfNeeded()
  212. self.view.bringSubviewToFront(self.playerVc.view)
  213. }
  214. }
  215. func hidePlayerVc() {
  216. UIView.animate(withDuration: 0.2) {
  217. self.playerVc.view.snp.remakeConstraints { make in
  218. make.top.equalToSuperview().offset(UIScreen.kScreenHeight)
  219. make.leading.trailing.equalToSuperview()
  220. make.height.equalTo(UIScreen.kScreenHeight)
  221. }
  222. self.view.setNeedsLayout()
  223. self.view.layoutIfNeeded()
  224. self.view.bringSubviewToFront(self.playerVc.view)
  225. }
  226. }
  227. }
  228. // MARK: 进到首页后需要做的处理
  229. extension TSTabBarController {
  230. /// 暂时没用,后续迭代
  231. func scheduleDailyNotification() {
  232. // 创建通知内容
  233. let content = UNMutableNotificationContent()
  234. content.title = "🎧 ≡ ◁◁ ❚❚ ▷▷ ↻"
  235. content.body = "♬ ♬ ♩ ♡ ♪ ♪ ♫ ♭ ♫ ♡"
  236. content.sound = UNNotificationSound.default
  237. // 创建通知触发条件
  238. var dateComponents = DateComponents()
  239. dateComponents.hour = 21 // 24小时制,20点即晚上8点
  240. let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
  241. // 创建通知请求
  242. let request = UNNotificationRequest(identifier: "DailyNotification", content: content, trigger: trigger)
  243. // 将通知添加到通知中心
  244. UNUserNotificationCenter.current().add(request) { error in
  245. if let error = error {
  246. print("添加通知失败: \(error.localizedDescription)")
  247. }
  248. }
  249. }
  250. }