TabBarCoordinator.swift 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /*****************************************************************************
  2. * TabBarCoordinator.swift
  3. * VLC for iOS
  4. *****************************************************************************
  5. * Copyright (c) 2018 VideoLAN. All rights reserved.
  6. * $Id$
  7. *
  8. * Authors: Carola Nitz <nitz.carola # gmail.com>
  9. *
  10. * Refer to the COPYING file of the official project for license.
  11. *****************************************************************************/
  12. class TabBarCoordinator: NSObject {
  13. private var tabBarController: UITabBarController
  14. private var services: Services
  15. private lazy var editToolbar = EditToolbar()
  16. init(tabBarController: UITabBarController, services: Services) {
  17. self.tabBarController = tabBarController
  18. self.services = services
  19. super.init()
  20. setup()
  21. NotificationCenter.default.addObserver(self, selector: #selector(updateTheme), name: .VLCThemeDidChangeNotification, object: nil)
  22. }
  23. private func setup() {
  24. setupViewControllers()
  25. setupEditToolbar()
  26. updateTheme()
  27. }
  28. @objc func updateTheme() {
  29. editToolbar.backgroundColor = PresentationTheme.current.colors.tabBarColor
  30. //Setting this in appearanceManager doesn't update tabbar and UINavigationbar of the settingsViewController on change hence we do it here
  31. tabBarController.tabBar.isTranslucent = false
  32. tabBarController.tabBar.backgroundColor = PresentationTheme.current.colors.tabBarColor
  33. tabBarController.tabBar.barTintColor = PresentationTheme.current.colors.tabBarColor
  34. tabBarController.tabBar.itemPositioning = .fill
  35. tabBarController.viewControllers?.forEach {
  36. if let navController = $0 as? UINavigationController, navController.topViewController is VLCSettingsController {
  37. navController.navigationBar.isTranslucent = false
  38. navController.navigationBar.barTintColor = PresentationTheme.current.colors.navigationbarColor
  39. navController.navigationBar.tintColor = PresentationTheme.current.colors.orangeUI
  40. navController.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: PresentationTheme.current.colors.navigationbarTextColor]
  41. if #available(iOS 11.0, *) {
  42. navController.navigationBar.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor: PresentationTheme.current.colors.navigationbarTextColor]
  43. }
  44. if #available(iOS 13.0, *) {
  45. navController.navigationBar.standardAppearance = AppearanceManager.navigationbarAppearance()
  46. navController.navigationBar.scrollEdgeAppearance = AppearanceManager.navigationbarAppearance()
  47. }
  48. }
  49. }
  50. }
  51. private func setupViewControllers() {
  52. let controllers: [UIViewController] = [
  53. VideoViewController(services: services),
  54. AudioViewController(services: services),
  55. PlaylistViewController(services: services),
  56. VLCServerListViewController(nibName: nil, bundle: nil),
  57. VLCSettingsController(mediaLibraryService: services.medialibraryService)
  58. ]
  59. tabBarController.viewControllers = controllers.map { UINavigationController(rootViewController: $0) }
  60. }
  61. func handleShortcutItem(_ item: UIApplicationShortcutItem) {
  62. switch item.type {
  63. case kVLCApplicationShortcutLocalVideo:
  64. tabBarController.selectedIndex = tabBarController.viewControllers?.firstIndex(where: { vc -> Bool in
  65. vc is VideoViewController
  66. }) ?? 0
  67. case kVLCApplicationShortcutLocalAudio:
  68. tabBarController.selectedIndex = tabBarController.viewControllers?.firstIndex(where: { vc -> Bool in
  69. vc is AudioViewController
  70. }) ?? 1
  71. case kVLCApplicationShortcutPlaylist:
  72. tabBarController.selectedIndex = tabBarController.viewControllers?.firstIndex(where: { vc -> Bool in
  73. vc is PlaylistViewController
  74. }) ?? 2
  75. case kVLCApplicationShortcutNetwork:
  76. tabBarController.selectedIndex = tabBarController.viewControllers?.firstIndex(where: { vc -> Bool in
  77. vc is VLCServerListViewController
  78. }) ?? 3
  79. default:
  80. assertionFailure("unhandled shortcut")
  81. }
  82. }
  83. }
  84. // MARK: - Edit ToolBar
  85. private extension TabBarCoordinator {
  86. func setupEditToolbar() {
  87. editToolbar.isHidden = true
  88. editToolbar.translatesAutoresizingMaskIntoConstraints = false
  89. tabBarController.tabBar.addSubview(editToolbar)
  90. tabBarController.tabBar.bringSubviewToFront(editToolbar)
  91. let view = tabBarController.tabBar
  92. var guide: LayoutAnchorContainer = view
  93. if #available(iOS 11.0, *) {
  94. guide = view.safeAreaLayoutGuide
  95. }
  96. NSLayoutConstraint.activate([
  97. editToolbar.leadingAnchor.constraint(equalTo: view.leadingAnchor),
  98. editToolbar.trailingAnchor.constraint(equalTo: view.trailingAnchor),
  99. editToolbar.topAnchor.constraint(equalTo: guide.topAnchor),
  100. editToolbar.bottomAnchor.constraint(equalTo: guide.bottomAnchor),
  101. ])
  102. }
  103. }
  104. extension UITabBarController {
  105. open override var preferredStatusBarStyle: UIStatusBarStyle {
  106. return PresentationTheme.current.colors.statusBarStyle
  107. }
  108. override open func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
  109. super.traitCollectionDidChange(previousTraitCollection)
  110. if #available(iOS 13.0, *) {
  111. guard previousTraitCollection?.userInterfaceStyle != traitCollection.userInterfaceStyle else {
  112. // Since traitCollectionDidChange is called in, for example rotations, we make sure that
  113. // there was a userInterfaceStyle change.
  114. return
  115. }
  116. guard UserDefaults.standard.integer(forKey: kVLCSettingAppTheme) == kVLCSettingAppThemeSystem else {
  117. // Theme is specificly set, do not follow systeme theme.
  118. return
  119. }
  120. let isSystemDarkTheme = traitCollection.userInterfaceStyle == .dark
  121. PresentationTheme.current = isSystemDarkTheme ? PresentationTheme.darkTheme : PresentationTheme.brightTheme
  122. }
  123. }
  124. }
  125. // MARK: UITabBarController - Edit
  126. extension UITabBarController {
  127. func editToolBar() -> EditToolbar? {
  128. return tabBar.subviews.filter() { $0 is EditToolbar }.first as? EditToolbar
  129. }
  130. func displayEditToolbar(with model: MediaLibraryBaseModel) {
  131. guard let editToolbar = editToolBar() else {
  132. return
  133. }
  134. editToolbar.updateEditToolbar(for: model)
  135. editToolbar.isHidden = false
  136. }
  137. func hideEditToolbar() {
  138. guard let editToolbar = editToolBar() else {
  139. return
  140. }
  141. editToolbar.isHidden = true
  142. }
  143. }