PhotoLibraryViewController.swift 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. //
  2. // ALImagePickerViewController.swift
  3. // ALImagePickerViewController
  4. //
  5. // Created by Alex Littlejohn on 2015/06/09.
  6. // Copyright (c) 2015 zero. All rights reserved.
  7. //
  8. // Modified by Kevin Kieffer on 2019/08/06. Changes as follows:
  9. // Adding a pinch gesture to increase or decrease the number of columns shown, up to a min or max value
  10. import UIKit
  11. import Photos
  12. internal let ImageCellIdentifier = "ImageCell"
  13. internal let defaultItemSpacing: CGFloat = 1
  14. public typealias PhotoLibraryViewSelectionComplete = (PHAsset?) -> Void
  15. public class PhotoLibraryViewController: UIViewController {
  16. internal var assets: PHFetchResult<PHAsset>? = nil
  17. private var columns = CameraGlobals.DEFAULT_COLUMNS
  18. public var onSelectionComplete: PhotoLibraryViewSelectionComplete?
  19. private lazy var collectionView: UICollectionView = {
  20. let layout = UICollectionViewFlowLayout()
  21. layout.itemSize = CameraGlobals.shared.photoLibraryThumbnailSize(withColumns: columns)
  22. layout.minimumInteritemSpacing = defaultItemSpacing
  23. layout.minimumLineSpacing = defaultItemSpacing
  24. layout.sectionInset = UIEdgeInsets.zero
  25. let collectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
  26. collectionView.translatesAutoresizingMaskIntoConstraints = false
  27. collectionView.backgroundColor = UIColor.clear
  28. return collectionView
  29. }()
  30. public override func viewDidLoad() {
  31. super.viewDidLoad()
  32. setNeedsStatusBarAppearanceUpdate()
  33. let buttonImage = UIImage(named: "libraryCancel", in: CameraGlobals.shared.bundle, compatibleWith: nil)?.withRenderingMode(UIImage.RenderingMode.alwaysOriginal)
  34. navigationItem.leftBarButtonItem = UIBarButtonItem(image: buttonImage,
  35. style: UIBarButtonItem.Style.plain,
  36. target: self,
  37. action: #selector(dismissLibrary))
  38. view.backgroundColor = UIColor(white: 0.2, alpha: 1)
  39. view.addSubview(collectionView)
  40. _ = ImageFetcher()
  41. .onFailure(onFailure)
  42. .onSuccess(onSuccess)
  43. .fetch()
  44. let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(pinch(gesture:)))
  45. view.addGestureRecognizer(pinchGesture)
  46. }
  47. public override func viewWillLayoutSubviews() {
  48. super.viewWillLayoutSubviews()
  49. collectionView.frame = view.bounds
  50. }
  51. public override var preferredStatusBarStyle: UIStatusBarStyle {
  52. return UIStatusBarStyle.lightContent
  53. }
  54. public func present(_ inViewController: UIViewController, animated: Bool) {
  55. let navigationController = UINavigationController(rootViewController: self)
  56. navigationController.navigationBar.barTintColor = UIColor.black
  57. navigationController.navigationBar.barStyle = UIBarStyle.black
  58. inViewController.present(navigationController, animated: animated, completion: nil)
  59. }
  60. @objc public func dismissLibrary() {
  61. onSelectionComplete?(nil)
  62. }
  63. @objc internal func pinch(gesture: UIPinchGestureRecognizer) {
  64. switch gesture.state {
  65. case .began, .changed:
  66. if gesture.scale > CGFloat(1.2) && columns > CameraGlobals.MIN_COLUMNS {
  67. gesture.scale = CGFloat(1.0)
  68. columns -= 1
  69. collectionView.collectionViewLayout.invalidateLayout()
  70. }
  71. else if gesture.scale < CGFloat(0.8) && columns < CameraGlobals.MAX_COLUMNS {
  72. gesture.scale = CGFloat(1.0)
  73. columns += 1
  74. collectionView.collectionViewLayout.invalidateLayout()
  75. }
  76. case .ended:
  77. gesture.scale = CGFloat(1.0)
  78. default:
  79. break
  80. }
  81. }
  82. private func onSuccess(_ photos: PHFetchResult<PHAsset>) {
  83. assets = photos
  84. configureCollectionView()
  85. }
  86. private func onFailure(_ error: NSError) {
  87. let permissionsView = PermissionsView(frame: view.bounds)
  88. permissionsView.titleLabel.text = localizedString("permissions.library.title")
  89. permissionsView.descriptionLabel.text = localizedString("permissions.library.description")
  90. view.addSubview(permissionsView)
  91. }
  92. private func configureCollectionView() {
  93. collectionView.register(ImageCell.self, forCellWithReuseIdentifier: ImageCellIdentifier)
  94. collectionView.delegate = self
  95. collectionView.dataSource = self
  96. }
  97. internal func itemAtIndexPath(_ indexPath: IndexPath) -> PHAsset? {
  98. return assets?[(indexPath as NSIndexPath).row]
  99. }
  100. }
  101. // MARK: - UICollectionViewDataSource -
  102. extension PhotoLibraryViewController : UICollectionViewDataSource {
  103. public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
  104. return assets?.count ?? 0
  105. }
  106. @objc(collectionView:willDisplayCell:forItemAtIndexPath:) public func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
  107. if cell is ImageCell {
  108. if let model = itemAtIndexPath(indexPath) {
  109. (cell as! ImageCell).configureWithModel(model)
  110. }
  111. }
  112. }
  113. public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
  114. return collectionView.dequeueReusableCell(withReuseIdentifier: ImageCellIdentifier, for: indexPath)
  115. }
  116. }
  117. // MARK: - UICollectionViewDelegate -
  118. extension PhotoLibraryViewController : UICollectionViewDelegateFlowLayout {
  119. public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
  120. onSelectionComplete?(itemAtIndexPath(indexPath))
  121. }
  122. public func collectionView(_ collectionView: UICollectionView,
  123. layout collectionViewLayout: UICollectionViewLayout,
  124. sizeForItemAt indexPath: IndexPath) -> CGSize {
  125. return CameraGlobals.shared.photoLibraryThumbnailSize(withColumns: columns)
  126. }
  127. }