MediaViewController.swift 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*****************************************************************************
  2. * MediaViewController.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. * Mike JS. Choi <mkchoi212 # icloud.com>
  10. *
  11. * Refer to the COPYING file of the official project for license.
  12. *****************************************************************************/
  13. import Foundation
  14. @objc public protocol VLCMediaViewControllerDelegate: class {
  15. func mediaViewControllerDidSelectMediaObject(_ mediaViewController: VLCMediaViewController, mediaObject: NSManagedObject)
  16. func mediaViewControllerDidSelectSort(_ mediaViewController: VLCMediaViewController)
  17. }
  18. public class VLCMediaViewController: UICollectionViewController, UISearchResultsUpdating, UISearchControllerDelegate {
  19. private var services: Services
  20. private var mediaDataSourceAndDelegate: MediaDataSourceAndDelegate?
  21. private var searchController: UISearchController?
  22. private let searchDataSource = VLCLibrarySearchDisplayDataSource()
  23. private var mediaType: VLCMediaType
  24. public weak var delegate: VLCMediaViewControllerDelegate?
  25. @available(iOS 11.0, *)
  26. lazy var dragAndDropManager: VLCDragAndDropManager = {
  27. let dragAndDropManager = VLCDragAndDropManager(type: mediaType)
  28. dragAndDropManager.delegate = services.mediaDataSource
  29. return dragAndDropManager
  30. }()
  31. lazy var emptyView: VLCEmptyLibraryView = {
  32. let name = String(describing: VLCEmptyLibraryView.self)
  33. let nib = Bundle.main.loadNibNamed(name, owner: self, options: nil)
  34. guard let emptyView = nib?.first as? VLCEmptyLibraryView else { fatalError("Can't find nib for \(name)") }
  35. emptyView.frame = view.bounds
  36. return emptyView
  37. }()
  38. @available(*, unavailable)
  39. init() {
  40. fatalError()
  41. }
  42. init(services: Services, type: VLCMediaType) {
  43. self.services = services
  44. mediaType = type
  45. super.init(collectionViewLayout: UICollectionViewFlowLayout())
  46. NotificationCenter.default.addObserver(self, selector: #selector(themeDidChange), name: .VLCThemeDidChangeNotification, object: nil)
  47. if mediaType.category == .video {
  48. NotificationCenter.default.addObserver(self, selector: #selector(reloadData), name: .VLCAllVideosDidChangeNotification, object: nil)
  49. } else {
  50. NotificationCenter.default.addObserver(self, selector: #selector(reloadData), name: .VLCTracksDidChangeNotification, object: nil)
  51. }
  52. }
  53. @objc func reloadData() {
  54. collectionView?.reloadData()
  55. displayEmptyViewIfNeeded()
  56. }
  57. @available(*, unavailable)
  58. required public init?(coder aDecoder: NSCoder) {
  59. fatalError("init(coder: ) has not been implemented")
  60. }
  61. override public func viewDidLoad() {
  62. super.viewDidLoad()
  63. setupCollectionView()
  64. setupSearchController()
  65. setupNavigationBar()
  66. _ = (MLMediaLibrary.sharedMediaLibrary() as! MLMediaLibrary).libraryDidAppear()
  67. }
  68. @objc func themeDidChange() {
  69. collectionView?.backgroundColor = PresentationTheme.current.colors.background
  70. }
  71. func setupCollectionView() {
  72. mediaDataSourceAndDelegate = MediaDataSourceAndDelegate(services: services, type:mediaType)
  73. mediaDataSourceAndDelegate?.delegate = self
  74. let playlistnib = UINib(nibName: "VLCPlaylistCollectionViewCell", bundle:nil)
  75. collectionView?.register(playlistnib, forCellWithReuseIdentifier: VLCPlaylistCollectionViewCell.cellIdentifier())
  76. collectionView?.backgroundColor = PresentationTheme.current.colors.background
  77. collectionView?.alwaysBounceVertical = true
  78. collectionView?.dataSource = mediaDataSourceAndDelegate
  79. collectionView?.delegate = mediaDataSourceAndDelegate
  80. if #available(iOS 11.0, *) {
  81. collectionView?.dragDelegate = dragAndDropManager
  82. collectionView?.dropDelegate = dragAndDropManager
  83. }
  84. }
  85. override public func viewDidAppear(_ animated: Bool) {
  86. super.viewDidAppear(animated)
  87. reloadData()
  88. }
  89. func setupSearchController() {
  90. searchController = UISearchController(searchResultsController: nil)
  91. searchController?.searchResultsUpdater = self
  92. searchController?.dimsBackgroundDuringPresentation = false
  93. searchController?.delegate = self
  94. if let textfield = searchController?.searchBar.value(forKey: "searchField") as? UITextField {
  95. if let backgroundview = textfield.subviews.first {
  96. backgroundview.backgroundColor = UIColor.white
  97. backgroundview.layer.cornerRadius = 10
  98. backgroundview.clipsToBounds = true
  99. }
  100. }
  101. if #available(iOS 11.0, *) {
  102. navigationItem.searchController = searchController
  103. } else {
  104. navigationItem.titleView = searchController?.searchBar
  105. searchController?.hidesNavigationBarDuringPresentation = false
  106. }
  107. }
  108. func setupNavigationBar() {
  109. navigationItem.leftBarButtonItem = UIBarButtonItem(title: NSLocalizedString("SORT", comment: ""), style: .plain, target: self, action: #selector(sort))
  110. }
  111. func displayEmptyViewIfNeeded() {
  112. collectionView?.backgroundView = collectionView?.numberOfItems(inSection: 0) == 0 ? emptyView : nil
  113. }
  114. @objc func sort() {
  115. delegate?.mediaViewControllerDidSelectSort(self)
  116. }
  117. override public func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
  118. collectionView?.collectionViewLayout.invalidateLayout()
  119. }
  120. // MARK: - MediaDatasourceAndDelegate
  121. override public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
  122. delegate?.mediaViewControllerDidSelectMediaObject(self, mediaObject: services.mediaDataSource.object(at: indexPath.row, subcategory: mediaType.subcategory))
  123. }
  124. // MARK: - Search
  125. public func updateSearchResults(for searchController: UISearchController) {
  126. searchDataSource.shouldReloadTable(forSearch: searchController.searchBar.text, searchableFiles: services.mediaDataSource.allObjects(for: mediaType.subcategory))
  127. collectionView?.reloadData()
  128. }
  129. public func didPresentSearchController(_ searchController: UISearchController) {
  130. collectionView?.dataSource = searchDataSource
  131. }
  132. public func didDismissSearchController(_ searchController: UISearchController) {
  133. collectionView?.dataSource = mediaDataSourceAndDelegate
  134. }
  135. }