Browse Source

fix avatar selection fix, credits to nayooti

cyberta 5 years ago
parent
commit
b83f65b153
100 changed files with 2145 additions and 1886 deletions
  1. 1 1
      Podfile
  2. 5 5
      Podfile.lock
  3. 0 24
      Pods/ALCameraViewController/ALCameraViewController/Utilities/CameraGlobals.swift
  4. 0 39
      Pods/ALCameraViewController/ALCameraViewController/Utilities/CroppingParameters.swift
  5. 0 408
      Pods/ALCameraViewController/ALCameraViewController/ViewController/ConfirmViewController.swift
  6. 0 286
      Pods/ALCameraViewController/ALCameraViewController/Views/CropOverlay.swift
  7. 0 149
      Pods/ALCameraViewController/README.md
  8. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraView.strings
  9. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/Contents.json
  10. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/cameraButton.imageset/Contents.json
  11. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/cameraButton.imageset/cameraButton.png
  12. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/cameraButton.imageset/cameraButton@2x.png
  13. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/cameraButton.imageset/cameraButton@3x.png
  14. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/cameraButtonHighlighted.imageset/Contents.json
  15. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/cameraButtonHighlighted.imageset/cameraButtonHighlighted.png
  16. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/cameraButtonHighlighted.imageset/cameraButtonHighlighted@2x.png
  17. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/cameraButtonHighlighted.imageset/cameraButtonHighlighted@3x.png
  18. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/closeButton.imageset/Contents.json
  19. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/closeButton.imageset/closeButton.png
  20. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/closeButton.imageset/closeButton@2x.png
  21. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/closeButton.imageset/closeButton@3x.png
  22. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/confirmButton.imageset/Contents.json
  23. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/confirmButton.imageset/confirmButton.png
  24. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/confirmButton.imageset/confirmButton@2x.png
  25. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/confirmButton.imageset/confirmButton@3x.png
  26. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashAutoIcon.imageset/Contents.json
  27. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashAutoIcon.imageset/flashAutoIcon.png
  28. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashAutoIcon.imageset/flashAutoIcon@2x.png
  29. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashAutoIcon.imageset/flashAutoIcon@3x.png
  30. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashOffIcon.imageset/Contents.json
  31. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashOffIcon.imageset/flashOffIcon.png
  32. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashOffIcon.imageset/flashOffIcon@2x.png
  33. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashOffIcon.imageset/flashOffIcon@3x.png
  34. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashOnIcon.imageset/Contents.json
  35. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashOnIcon.imageset/flashOnIcon.png
  36. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashOnIcon.imageset/flashOnIcon@2x.png
  37. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashOnIcon.imageset/flashOnIcon@3x.png
  38. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryButton.imageset/Contents.json
  39. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryButton.imageset/libraryButton.png
  40. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryButton.imageset/libraryButton@2x.png
  41. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryButton.imageset/libraryButton@3x.png
  42. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryCancel.imageset/Contents.json
  43. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryCancel.imageset/libraryCancel.png
  44. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryCancel.imageset/libraryCancel@2x.png
  45. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryCancel.imageset/libraryCancel@3x.png
  46. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryConfirm.imageset/Contents.json
  47. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryConfirm.imageset/libraryConfirm.png
  48. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryConfirm.imageset/libraryConfirm@2x.png
  49. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryConfirm.imageset/libraryConfirm@3x.png
  50. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/permissionsIcon.imageset/Contents.json
  51. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/permissionsIcon.imageset/cameraPermissionsIcon.png
  52. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/permissionsIcon.imageset/cameraPermissionsIcon@2x.png
  53. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/permissionsIcon.imageset/cameraPermissionsIcon@3x.png
  54. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/placeholder.imageset/Contents.json
  55. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/placeholder.imageset/placeholder.png
  56. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/placeholder.imageset/placeholder@2x.png
  57. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/placeholder.imageset/placeholder@3x.png
  58. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/retakeButton.imageset/Contents.json
  59. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/retakeButton.imageset/retakeButton.png
  60. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/retakeButton.imageset/retakeButton@2x.png
  61. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/retakeButton.imageset/retakeButton@3x.png
  62. 23 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/rotateButton.imageset/Contents.json
  63. BIN
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/rotateButton.imageset/rotateButton@1x.png
  64. BIN
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/rotateButton.imageset/rotateButton@2x.png
  65. BIN
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/rotateButton.imageset/rotateButton@3x.png
  66. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/swapButton.imageset/Contents.json
  67. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/swapButton.imageset/swapButton.png
  68. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/swapButton.imageset/swapButton@2x.png
  69. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/swapButton.imageset/swapButton@3x.png
  70. 56 0
      Pods/KK-ALCameraViewController/ALCameraViewController/Utilities/CameraGlobals.swift
  71. 1 1
      Pods/KK-ALCameraViewController/ALCameraViewController/Utilities/CameraShot.swift
  72. 65 0
      Pods/KK-ALCameraViewController/ALCameraViewController/Utilities/CroppingParameters.swift
  73. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/Utilities/ImageFetcher.swift
  74. 2 1
      Pods/KK-ALCameraViewController/ALCameraViewController/Utilities/PhotoLibraryAuthorizer.swift
  75. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/Utilities/SingleImageFetcher.swift
  76. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/Utilities/SingleImageSaver.swift
  77. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/Utilities/UIButtonExtensions.swift
  78. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/Utilities/UIViewExtensions.swift
  79. 3 8
      Pods/KK-ALCameraViewController/ALCameraViewController/Utilities/Utilities.swift
  80. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/Utilities/VolumeControl.swift
  81. 58 56
      Pods/KK-ALCameraViewController/ALCameraViewController/ViewController/CameraViewController.swift
  82. 129 22
      Pods/KK-ALCameraViewController/ALCameraViewController/ViewController/CameraViewControllerConstraint.swift
  83. 500 0
      Pods/KK-ALCameraViewController/ALCameraViewController/ViewController/ConfirmViewController.swift
  84. 37 67
      Pods/KK-ALCameraViewController/ALCameraViewController/ViewController/ConfirmViewController.xib
  85. 41 1
      Pods/KK-ALCameraViewController/ALCameraViewController/ViewController/PhotoLibraryViewController.swift
  86. 63 2
      Pods/KK-ALCameraViewController/ALCameraViewController/Views/CameraView.swift
  87. 287 0
      Pods/KK-ALCameraViewController/ALCameraViewController/Views/CropOverlay.swift
  88. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/Views/ImageCell.swift
  89. 0 0
      Pods/KK-ALCameraViewController/ALCameraViewController/Views/PermissionsView.swift
  90. 0 0
      Pods/KK-ALCameraViewController/LICENSE
  91. 58 0
      Pods/KK-ALCameraViewController/README.md
  92. 5 5
      Pods/Manifest.lock
  93. 797 797
      Pods/Pods.xcodeproj/project.pbxproj
  94. 0 5
      Pods/Target Support Files/ALCameraViewController/ALCameraViewController-dummy.m
  95. 0 6
      Pods/Target Support Files/ALCameraViewController/ALCameraViewController.modulemap
  96. 1 1
      Pods/Target Support Files/KK-ALCameraViewController/KK-ALCameraViewController-Info.plist
  97. 5 0
      Pods/Target Support Files/KK-ALCameraViewController/KK-ALCameraViewController-dummy.m
  98. 0 0
      Pods/Target Support Files/KK-ALCameraViewController/KK-ALCameraViewController-prefix.pch
  99. 2 2
      Pods/Target Support Files/KK-ALCameraViewController/KK-ALCameraViewController-umbrella.h
  100. 6 0
      Pods/Target Support Files/KK-ALCameraViewController/KK-ALCameraViewController.modulemap

+ 1 - 1
Podfile

@@ -8,7 +8,7 @@ target 'deltachat-ios' do
 
   pod 'SwiftLint'
   pod 'SwiftFormat/CLI'
-  pod 'ALCameraViewController'
+  pod 'KK-ALCameraViewController'
   # pod 'openssl-ios-bitcode'
   pod 'ReachabilitySwift'
   pod 'UICircularProgressRing'

+ 5 - 5
Podfile.lock

@@ -1,10 +1,10 @@
 PODS:
-  - ALCameraViewController (3.1)
   - DBDebugToolkit (0.5.0)
   - InputBarAccessoryView (4.3.1):
     - InputBarAccessoryView/Core (= 4.3.1)
   - InputBarAccessoryView/Core (4.3.1)
   - JGProgressHUD (2.0.3)
+  - KK-ALCameraViewController (4.1.0)
   - ReachabilitySwift (4.3.1)
   - SCSiriWaveformView (1.1.1)
   - SwiftFormat/CLI (0.40.9)
@@ -13,10 +13,10 @@ PODS:
   - UICircularProgressRing (6.2.0)
 
 DEPENDENCIES:
-  - ALCameraViewController
   - DBDebugToolkit
   - InputBarAccessoryView
   - JGProgressHUD
+  - KK-ALCameraViewController
   - ReachabilitySwift
   - SCSiriWaveformView
   - SwiftFormat/CLI
@@ -26,10 +26,10 @@ DEPENDENCIES:
 
 SPEC REPOS:
   trunk:
-    - ALCameraViewController
     - DBDebugToolkit
     - InputBarAccessoryView
     - JGProgressHUD
+    - KK-ALCameraViewController
     - ReachabilitySwift
     - SCSiriWaveformView
     - SwiftFormat
@@ -38,10 +38,10 @@ SPEC REPOS:
     - UICircularProgressRing
 
 SPEC CHECKSUMS:
-  ALCameraViewController: 144dea45fd749a623aafd8cb7b10cea88499fcc3
   DBDebugToolkit: c04bb6f618051d3de447a4b4323f37826116cfed
   InputBarAccessoryView: 58a348be7ea2736c7eec60e5c315511c2dbb39fd
   JGProgressHUD: 12b20a8f4ffe05258f8635c1ab92816e451f904d
+  KK-ALCameraViewController: ea8d8b24c9a7b92f61508a5a41ef8332f4ef7903
   ReachabilitySwift: 4032e2f59586e11e3b0ebe15b167abdd587a388b
   SCSiriWaveformView: 15b9dd6f94c7536e2032b34a35c6ff74d38c7411
   SwiftFormat: 6b67b6e7fe73d664f0cbb4f13721f130462c86a5
@@ -49,6 +49,6 @@ SPEC CHECKSUMS:
   SwiftyBeaver: 4cc0080d2e23f980652e28978db11a5c9da39165
   UICircularProgressRing: 0ff679b05a17f15ad6301a7886686837b8c301a9
 
-PODFILE CHECKSUM: 055466769932ef70c4999b1faacbdf7883a8e6d8
+PODFILE CHECKSUM: a98070d2fb3a559fc76c7d76ff4cf4ea68108ac1
 
 COCOAPODS: 1.8.4

+ 0 - 24
Pods/ALCameraViewController/ALCameraViewController/Utilities/CameraGlobals.swift

@@ -1,24 +0,0 @@
-//
-//  CameraGlobals.swift
-//  ALCameraViewController
-//
-//  Created by Alex Littlejohn on 2016/02/16.
-//  Copyright © 2016 zero. All rights reserved.
-//
-
-import UIKit
-import AVFoundation
-
-internal let itemSpacing: CGFloat = 1
-internal let columns: CGFloat = 4
-internal let thumbnailDimension = (UIScreen.main.bounds.width - ((columns * itemSpacing) - itemSpacing))/columns
-internal let scale = UIScreen.main.scale
-
-public class CameraGlobals {
-    public static let shared = CameraGlobals()
-    
-    public var bundle = Bundle(for: CameraViewController.self)
-    public var stringsTable = "CameraView"
-    public var photoLibraryThumbnailSize = CGSize(width: thumbnailDimension, height: thumbnailDimension)
-    public var defaultCameraPosition = AVCaptureDevice.Position.back
-}

+ 0 - 39
Pods/ALCameraViewController/ALCameraViewController/Utilities/CroppingParameters.swift

@@ -1,39 +0,0 @@
-//
-//  CroppingParameters.swift
-//  ALCameraViewController
-//
-//  Created by Guillaume Bellut on 02/09/2017.
-//  Copyright © 2017 zero. All rights reserved.
-//
-
-import UIKit
-
-public struct CroppingParameters {
-
-    /// Enable the cropping feature.
-    /// Default value is set to false.
-    var isEnabled: Bool
-
-    /// Allow the cropping area to be resized by the user.
-    /// Default value is set to true.
-    var allowResizing: Bool
-
-    /// Allow the cropping area to be moved by the user.
-    /// Default value is set to false.
-    var allowMoving: Bool
-
-    /// Prevent the user to resize the cropping area below a minimum size.
-    /// Default value is (60, 60). Below this value, corner buttons will overlap.
-    var minimumSize: CGSize
-
-    public init(isEnabled: Bool = false,
-                allowResizing: Bool = true,
-                allowMoving: Bool = true,
-         minimumSize: CGSize = CGSize(width: 60, height: 60)) {
-
-        self.isEnabled = isEnabled
-        self.allowResizing = allowResizing
-        self.allowMoving = allowMoving
-        self.minimumSize = minimumSize
-    }
-}

+ 0 - 408
Pods/ALCameraViewController/ALCameraViewController/ViewController/ConfirmViewController.swift

@@ -1,408 +0,0 @@
-//
-//  ALConfirmViewController.swift
-//  ALCameraViewController
-//
-//  Created by Alex Littlejohn on 2015/06/30.
-//  Copyright (c) 2015 zero. All rights reserved.
-//
-
-import UIKit
-import Photos
-
-public class ConfirmViewController: UIViewController {
-	
-	let imageView = UIImageView()
-	@IBOutlet weak var scrollView: UIScrollView!
-	@IBOutlet weak var cancelButton: UIButton!
-	@IBOutlet weak var confirmButton: UIButton!
-	@IBOutlet weak var centeredView: UIView!
-
-    private let cropOverlay = CropOverlay()
-    private var spinner: UIActivityIndicatorView? = nil
-    private var cropOverlayLeftConstraint = NSLayoutConstraint()
-    private var cropOverlayTopConstraint = NSLayoutConstraint()
-    private var cropOverlayWidthConstraint = NSLayoutConstraint()
-    private var cropOverlayHeightConstraint = NSLayoutConstraint()
-    private var isFirstLayout = true
-	
-    var croppingParameters: CroppingParameters {
-        didSet {
-            cropOverlay.isResizable = croppingParameters.allowResizing
-            cropOverlay.minimumSize = croppingParameters.minimumSize
-        }
-    }
-
-    private var scrollViewVisibleSize: CGSize {
-        let contentInset = scrollView.contentInset
-        let scrollViewSize = scrollView.bounds.standardized.size
-        let width = scrollViewSize.width - contentInset.left - contentInset.right
-        let height = scrollViewSize.height - contentInset.top - contentInset.bottom
-        return CGSize(width:width, height:height)
-    }
-
-    private var scrollViewCenter: CGPoint {
-        let scrollViewSize = scrollViewVisibleSize
-        return CGPoint(x: scrollViewSize.width / 2.0,
-                       y: scrollViewSize.height / 2.0)
-    }
-
-    private let cropOverlayDefaultPadding: CGFloat = 20
-    private var cropOverlayDefaultFrame: CGRect {
-        let buttonsViewGap: CGFloat = 20 * 2 + 64
-        let centeredViewBounds: CGRect
-        if view.bounds.size.height > view.bounds.size.width {
-            centeredViewBounds = CGRect(x: 0,
-                                        y: 0,
-                                        width: view.bounds.size.width,
-                                        height: view.bounds.size.height - buttonsViewGap)
-        } else {
-            centeredViewBounds = CGRect(x: 0,
-                                        y: 0,
-                                        width: view.bounds.size.width - buttonsViewGap,
-                                        height: view.bounds.size.height)
-        }
-        
-        let cropOverlayWidth = min(centeredViewBounds.size.width, centeredViewBounds.size.height) - 2 * cropOverlayDefaultPadding
-        let cropOverlayX = centeredViewBounds.size.width / 2 - cropOverlayWidth / 2
-        let cropOverlayY = centeredViewBounds.size.height / 2 - cropOverlayWidth / 2
-
-        return CGRect(x: cropOverlayX,
-                      y: cropOverlayY,
-                      width: cropOverlayWidth,
-                      height: cropOverlayWidth)
-    }
-	
-	public var onComplete: CameraViewCompletion?
-
-	let asset: PHAsset?
-	let image: UIImage?
-	
-	public init(image: UIImage, croppingParameters: CroppingParameters) {
-		self.croppingParameters = croppingParameters
-		self.asset = nil
-		self.image = image
-		super.init(nibName: "ConfirmViewController", bundle: CameraGlobals.shared.bundle)
-	}
-	
-	public init(asset: PHAsset, croppingParameters: CroppingParameters) {
-		self.croppingParameters = croppingParameters
-		self.asset = asset
-		self.image = nil
-		super.init(nibName: "ConfirmViewController", bundle: CameraGlobals.shared.bundle)
-	}
-	
-    public required init?(coder aDecoder: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
-	}
-	
-	public override var prefersStatusBarHidden: Bool {
-		return true
-	}
-	
-	public override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
-		return UIStatusBarAnimation.slide
-	}
-	
-	public override func viewDidLoad() {
-		super.viewDidLoad()
-
-		view.backgroundColor = UIColor.black
-
-        loadScrollView()
-        loadCropOverlay()
-
-		showSpinner()
-		
-		disable()
-		
-		if let asset = asset {
-			_ = SingleImageFetcher()
-				.setAsset(asset)
-				.setTargetSize(largestPhotoSize())
-				.onSuccess { [weak self] image in
-					self?.configureWithImage(image)
-					self?.hideSpinner()
-					self?.enable()
-				}
-				.onFailure { [weak self] error in
-					self?.hideSpinner()
-				}
-				.fetch()
-		} else if let image = image {
-			configureWithImage(image)
-			hideSpinner()
-			enable()
-		}
-	}
-
-    public override func viewDidLayoutSubviews() {
-        super.viewDidLayoutSubviews()
-
-        if isFirstLayout {
-            isFirstLayout = false
-            activateCropOverlayConstraint()
-            spinner?.center = centeredView.center
-        }
-    }
-
-    private func activateCropOverlayConstraint() {
-        cropOverlayLeftConstraint.constant = cropOverlayDefaultFrame.origin.x
-        cropOverlayTopConstraint.constant = cropOverlayDefaultFrame.origin.y
-        cropOverlayWidthConstraint.constant = cropOverlayDefaultFrame.size.width
-        cropOverlayHeightConstraint.constant = cropOverlayDefaultFrame.size.height
-
-        cropOverlayLeftConstraint.isActive = true
-        cropOverlayTopConstraint.isActive = true
-        cropOverlayWidthConstraint.isActive = true
-        cropOverlayHeightConstraint.isActive = true
-    }
-
-    private func loadScrollView() {
-        scrollView.addSubview(imageView)
-        scrollView.delegate = self
-        scrollView.maximumZoomScale = 1
-    }
-
-    private func prepareScrollView() {
-        let scale = calculateMinimumScale(view.bounds.size)
-
-        scrollView.minimumZoomScale = scale
-        scrollView.zoomScale = scale
-
-        centerScrollViewContent()
-    }
-
-    private func loadCropOverlay() {
-        cropOverlay.translatesAutoresizingMaskIntoConstraints = false
-        view.addSubview(cropOverlay)
-
-        cropOverlayLeftConstraint = cropOverlay.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 0)
-        cropOverlayTopConstraint = cropOverlay.topAnchor.constraint(equalTo: view.topAnchor, constant: 0)
-        cropOverlayWidthConstraint = cropOverlay.widthAnchor.constraint(equalToConstant: 0)
-        cropOverlayHeightConstraint = cropOverlay.heightAnchor.constraint(equalToConstant: 0)
-
-        cropOverlay.delegate = self
-        cropOverlay.isHidden = !croppingParameters.isEnabled
-        cropOverlay.isResizable = croppingParameters.allowResizing
-        cropOverlay.isMovable = croppingParameters.allowMoving
-        cropOverlay.minimumSize = croppingParameters.minimumSize
-    }
-	
-	private func configureWithImage(_ image: UIImage) {
-		buttonActions()
-		
-		imageView.image = image
-		imageView.sizeToFit()
-        prepareScrollView()
-	}
-	
-	private func calculateMinimumScale(_ size: CGSize) -> CGFloat {
-		var _size = size
-		
-		if croppingParameters.isEnabled {
-            _size = cropOverlayDefaultFrame.size
-		}
-		
-		guard let image = imageView.image else {
-            return 1
-		}
-		
-		let scaleWidth = _size.width / image.size.width
-		let scaleHeight = _size.height / image.size.height
-
-		return min(scaleWidth, scaleHeight)
-	}
-	
-	private func centerScrollViewContent() {
-        guard let image = imageView.image else {
-            return
-        }
-
-        let imgViewSize = imageView.frame.size
-        let imageSize = image.size
-
-        var realImgSize: CGSize
-        if imageSize.width / imageSize.height > imgViewSize.width / imgViewSize.height {
-            realImgSize = CGSize(width: imgViewSize.width,height: imgViewSize.width / imageSize.width * imageSize.height)
-        } else {
-            realImgSize = CGSize(width: imgViewSize.height / imageSize.height * imageSize.width, height: imgViewSize.height)
-        }
-
-        var frame = CGRect.zero
-        frame.size = realImgSize
-        imageView.frame = frame
-
-        let screenSize  = scrollView.frame.size
-        let offx = screenSize.width > realImgSize.width ? (screenSize.width - realImgSize.width) / 2 : 0
-        let offy = screenSize.height > realImgSize.height ? (screenSize.height - realImgSize.height) / 2 : 0
-        scrollView.contentInset = UIEdgeInsets(top: offy,
-                                               left: offx,
-                                               bottom: offy,
-                                               right: offx)
-	}
-	
-	private func buttonActions() {
-		confirmButton.action = { [weak self] in self?.confirmPhoto() }
-		cancelButton.action = { [weak self] in self?.cancel() }
-	}
-	
-	internal func cancel() {
-		onComplete?(nil, nil)
-	}
-	
-	internal func confirmPhoto() {
-		
-		guard let image = imageView.image else {
-			return
-		}
-		
-		disable()
-		
-		imageView.isHidden = true
-		
-		showSpinner()
-		
-		if let asset = asset {
-			var fetcher = SingleImageFetcher()
-				.onSuccess { [weak self] image in
-					self?.onComplete?(image, self?.asset)
-					self?.hideSpinner()
-					self?.enable()
-				}
-				.onFailure { [weak self] error in
-					self?.hideSpinner()
-					self?.showNoImageScreen(error)
-				}
-				.setAsset(asset)
-			if croppingParameters.isEnabled {
-				let rect = normalizedRect(makeProportionalCropRect(), orientation: image.imageOrientation)
-				fetcher = fetcher.setCropRect(rect)
-			}
-			
-			fetcher = fetcher.fetch()
-		} else {
-			var newImage = image
-			
-			if croppingParameters.isEnabled {
-				let cropRect = makeProportionalCropRect()
-				let resizedCropRect = CGRect(x: (image.size.width) * cropRect.origin.x,
-				                     y: (image.size.height) * cropRect.origin.y,
-				                     width: (image.size.width * cropRect.width),
-				                     height: (image.size.height * cropRect.height))
-				newImage = image.crop(rect: resizedCropRect)
-			}
-			
-			onComplete?(newImage, nil)
-			hideSpinner()
-			enable()
-		}
-	}
-	
-	func showSpinner() {
-		spinner = UIActivityIndicatorView()
-        spinner!.style = .white
-        spinner!.center = centeredView.center
-		spinner!.startAnimating()
-		
-		view.addSubview(spinner!)
-        view.bringSubviewToFront(spinner!)
-    }
-	
-	func hideSpinner() {
-		spinner?.stopAnimating()
-		spinner?.removeFromSuperview()
-	}
-	
-	func disable() {
-		confirmButton.isEnabled = false
-	}
-	
-	func enable() {
-		confirmButton.isEnabled = true
-	}
-	
-	func showNoImageScreen(_ error: NSError) {
-		let permissionsView = PermissionsView(frame: view.bounds)
-		
-		let desc = localizedString("error.cant-fetch-photo.description")
-		
-		permissionsView.configureInView(view, title: error.localizedDescription, description: desc, completion: { [weak self] in self?.cancel() })
-	}
-	
-	private func makeProportionalCropRect() -> CGRect {
-        var cropRect = cropOverlay.croppedRect
-        cropRect.origin.x += scrollView.contentOffset.x - imageView.frame.origin.x
-        cropRect.origin.y += scrollView.contentOffset.y - imageView.frame.origin.y
-
-		let normalizedX = max(0, cropRect.origin.x / imageView.frame.width)
-		let normalizedY = max(0, cropRect.origin.y / imageView.frame.height)
-
-        let extraWidth = min(0, cropRect.origin.x)
-        let extraHeight = min(0, cropRect.origin.y)
-
-		let normalizedWidth = min(1, (cropRect.width + extraWidth) / imageView.frame.width)
-		let normalizedHeight = min(1, (cropRect.height + extraHeight) / imageView.frame.height)
-		
-		return CGRect(x: normalizedX, y: normalizedY, width: normalizedWidth, height: normalizedHeight)
-	}
-	
-}
-
-extension ConfirmViewController: UIScrollViewDelegate {
-
-    public func viewForZooming(in scrollView: UIScrollView) -> UIView? {
-        return imageView
-    }
-
-    public func scrollViewDidZoom(_ scrollView: UIScrollView) {
-        centerScrollViewContent()
-    }
-}
-
-extension ConfirmViewController: CropOverlayDelegate {
-
-    func didMoveCropOverlay(newFrame: CGRect) {
-        cropOverlayLeftConstraint.constant = newFrame.origin.x
-        cropOverlayTopConstraint.constant = newFrame.origin.y
-        cropOverlayWidthConstraint.constant = newFrame.size.width
-        cropOverlayHeightConstraint.constant = newFrame.size.height
-    }
-}
-
-extension UIImage {
-	func crop(rect: CGRect) -> UIImage {
-
-		var rectTransform: CGAffineTransform
-		switch imageOrientation {
-		case .left:
-			rectTransform = CGAffineTransform(rotationAngle: radians(90)).translatedBy(x: 0, y: -size.height)
-		case .right:
-			rectTransform = CGAffineTransform(rotationAngle: radians(-90)).translatedBy(x: -size.width, y: 0)
-		case .down:
-			rectTransform = CGAffineTransform(rotationAngle: radians(-180)).translatedBy(x: -size.width, y: -size.height)
-		default:
-			rectTransform = CGAffineTransform.identity
-		}
-		
-		rectTransform = rectTransform.scaledBy(x: scale, y: scale)
-		
-		if let cropped = cgImage?.cropping(to: rect.applying(rectTransform)) {
-			return UIImage(cgImage: cropped, scale: scale, orientation: imageOrientation).fixOrientation()
-		}
-		
-		return self
-	}
-	
-	func fixOrientation() -> UIImage {
-		if imageOrientation == .up {
-			return self
-		}
-		
-		UIGraphicsBeginImageContextWithOptions(size, false, scale)
-		draw(in: CGRect(origin: .zero, size: size))
-		let normalizedImage: UIImage = UIGraphicsGetImageFromCurrentImageContext() ?? self
-		UIGraphicsEndImageContext()
-		
-		return normalizedImage
-	}
-}

+ 0 - 286
Pods/ALCameraViewController/ALCameraViewController/Views/CropOverlay.swift

@@ -1,286 +0,0 @@
-//
-//  NewCropOverlay.swift
-//  ALCameraViewController
-//
-//  Created by Guillaume Bellut on 12/10/2019.
-//  Copyright © 2019 zero. All rights reserved.
-//
-
-import UIKit
-
-protocol CropOverlayDelegate: class {
-    func didMoveCropOverlay(newFrame: CGRect)
-}
-
-internal class CropOverlay: UIView {
-
-    private let buttons = [UIButton(),  // top left
-                           UIButton(),  // top right
-                           UIButton(),  // bottom left
-                           UIButton()]  // bottom right
-    private let precisionView = UIView()    // view containing lines
-
-    private var cornerButtonWidth: CGFloat = 45
-
-    private let cornerLineDepth: CGFloat = 3
-    private var cornerLineLength: CGFloat {
-        return cornerButtonWidth / 2
-    }
-
-    private let lineDepth: CGFloat = 1
-
-    private let outterGapRatio: CGFloat = 1/3
-    private var outterGap: CGFloat {
-        return cornerButtonWidth * self.outterGapRatio
-    }
-
-    var isResizable: Bool = false
-    var isMovable: Bool = false
-    var minimumSize: CGSize = CGSize.zero
-    weak var delegate: CropOverlayDelegate?
-
-    var croppedRect: CGRect {
-        return CGRect(x: frame.origin.x + outterGap,
-                      y: frame.origin.y + outterGap,
-                      width: frame.size.width - 2 * outterGap,
-                      height: frame.size.height - 2 * outterGap)
-    }
-
-    internal override init(frame: CGRect) {
-        super.init(frame: frame)
-        setup()
-    }
-
-    internal required init?(coder aDecoder: NSCoder) {
-        super.init(coder: aDecoder)
-        setup()
-    }
-
-    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
-        let view = super.hitTest(point, with: event)
-
-        if !isMovable && isResizable {
-            let isButton = buttons.reduce(false) { $1.hitTest(convert(point, to: $1), with: event) != nil || $0 }
-            if !isButton {
-                return nil
-            }
-        }
-
-        return view
-    }
-
-    private func setup() {
-        let panGesture = UIPanGestureRecognizer(target: self, action: #selector(move(gestureRecognizer:)))
-        addGestureRecognizer(panGesture)
-
-        loadButtons()
-        loadPrecisionView()
-    }
-
-    private func loadButtons() {
-        buttons.forEach {
-            $0.translatesAutoresizingMaskIntoConstraints = false
-            addSubview($0)
-
-            let panGesture = UIPanGestureRecognizer(target: self, action: #selector(move(gestureRecognizer:)))
-            $0.addGestureRecognizer(panGesture)
-        }
-
-        buttons[0].topAnchor.constraint(equalTo: topAnchor).isActive = true
-        buttons[0].leftAnchor.constraint(equalTo: leftAnchor).isActive = true
-        buttons[0].widthAnchor.constraint(equalToConstant: cornerButtonWidth).isActive = true
-        buttons[0].heightAnchor.constraint(equalTo: buttons[0].widthAnchor).isActive = true
-
-        buttons[1].topAnchor.constraint(equalTo: topAnchor).isActive = true
-        buttons[1].rightAnchor.constraint(equalTo: rightAnchor).isActive = true
-        buttons[1].widthAnchor.constraint(equalToConstant: cornerButtonWidth).isActive = true
-        buttons[1].heightAnchor.constraint(equalTo: buttons[1].widthAnchor).isActive = true
-
-        buttons[2].bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
-        buttons[2].leftAnchor.constraint(equalTo: leftAnchor).isActive = true
-        buttons[2].widthAnchor.constraint(equalToConstant: cornerButtonWidth).isActive = true
-        buttons[2].heightAnchor.constraint(equalTo: buttons[2].widthAnchor).isActive = true
-
-        buttons[3].bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
-        buttons[3].rightAnchor.constraint(equalTo: rightAnchor).isActive = true
-        buttons[3].widthAnchor.constraint(equalToConstant: cornerButtonWidth).isActive = true
-        buttons[3].heightAnchor.constraint(equalTo: buttons[3].widthAnchor).isActive = true
-    }
-
-    private func loadPrecisionView() {
-        precisionView.translatesAutoresizingMaskIntoConstraints = false
-        addSubview(precisionView)
-
-        precisionView.isUserInteractionEnabled = false
-        precisionView.layer.borderWidth = 1
-        precisionView.layer.borderColor = UIColor.white.cgColor
-
-        precisionView.topAnchor.constraint(equalTo: topAnchor, constant: outterGap).isActive = true
-        precisionView.leftAnchor.constraint(equalTo: leftAnchor, constant: outterGap).isActive = true
-        precisionView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -outterGap).isActive = true
-        precisionView.rightAnchor.constraint(equalTo: rightAnchor, constant: -outterGap).isActive = true
-
-        loadCornerLines()
-        loadPrecisionLines()
-    }
-
-    private func loadCornerLines() {
-        let cornerLines = [UIView(), UIView(),  // top left
-            UIView(), UIView(),  // top right
-            UIView(), UIView(),  // bottom left
-            UIView(), UIView()]  // bottom right
-
-        cornerLines.forEach {
-            $0.translatesAutoresizingMaskIntoConstraints = false
-            precisionView.addSubview($0)
-
-            $0.isUserInteractionEnabled = false
-            $0.backgroundColor = .white
-
-            let index = cornerLines.firstIndex(of: $0)!
-
-            if index % 2 == 0 {
-                $0.widthAnchor.constraint(equalToConstant: cornerLineDepth).isActive = true
-                $0.heightAnchor.constraint(equalToConstant: cornerLineLength).isActive = true
-
-                if index <= 3 {
-                    $0.topAnchor.constraint(equalTo: precisionView.topAnchor, constant: -cornerLineDepth).isActive = true
-                } else {
-                    $0.bottomAnchor.constraint(equalTo: precisionView.bottomAnchor, constant: cornerLineDepth).isActive = true
-                }
-
-                if index % 4 == 0 {
-                    $0.rightAnchor.constraint(equalTo: precisionView.leftAnchor).isActive = true
-                } else {
-                    $0.leftAnchor.constraint(equalTo: precisionView.rightAnchor).isActive = true
-                }
-            } else {
-                $0.widthAnchor.constraint(equalToConstant: cornerLineLength).isActive = true
-                $0.heightAnchor.constraint(equalToConstant: cornerLineDepth).isActive = true
-
-                if index <= 3 {
-                    $0.leftAnchor.constraint(equalTo: precisionView.leftAnchor, constant: -cornerLineDepth).isActive = true
-                } else {
-                    $0.rightAnchor.constraint(equalTo: precisionView.rightAnchor, constant: cornerLineDepth).isActive = true
-                }
-
-                if index % 4 == 1 {
-                    $0.bottomAnchor.constraint(equalTo: precisionView.topAnchor).isActive = true
-                } else {
-                    $0.topAnchor.constraint(equalTo: precisionView.bottomAnchor).isActive = true
-                }
-            }
-        }
-    }
-
-    private func loadPrecisionLines() {
-        let centeredViews = [UIView(), UIView()]
-
-        centeredViews.forEach {
-            $0.translatesAutoresizingMaskIntoConstraints = false
-            precisionView.addSubview($0)
-
-            $0.isUserInteractionEnabled = false
-
-            $0.layer.borderWidth = 1
-            $0.layer.borderColor = UIColor.white.cgColor
-        }
-
-        // Horizontal view
-        centeredViews[0].leftAnchor.constraint(equalTo: precisionView.leftAnchor).isActive = true
-        centeredViews[0].rightAnchor.constraint(equalTo: precisionView.rightAnchor).isActive = true
-        centeredViews[0].heightAnchor.constraint(equalTo: precisionView.heightAnchor, multiplier: 1/3).isActive = true
-        centeredViews[0].centerYAnchor.constraint(equalTo: precisionView.centerYAnchor).isActive = true
-
-        // Vertical view
-        centeredViews[1].topAnchor.constraint(equalTo: precisionView.topAnchor).isActive = true
-        centeredViews[1].bottomAnchor.constraint(equalTo: precisionView.bottomAnchor).isActive = true
-        centeredViews[1].widthAnchor.constraint(equalTo: precisionView.widthAnchor, multiplier: 1/3).isActive = true
-        centeredViews[1].centerXAnchor.constraint(equalTo: precisionView.centerXAnchor).isActive = true
-    }
-
-    @objc func move(gestureRecognizer: UIPanGestureRecognizer) {
-        if isResizable, let button = gestureRecognizer.view as? UIButton {
-            if gestureRecognizer.state == .began || gestureRecognizer.state == .changed {
-                let translation = gestureRecognizer.translation(in: self)
-                let realMinimumSize = CGSize(width: minimumSize.width + 2 * outterGap,
-                                             height: minimumSize.height + 2 * outterGap)
-
-                var newFrame: CGRect
-
-                switch button {
-                case buttons[0]:    // Top Left
-                    let hasEnoughWidth = frame.size.width - translation.x >= realMinimumSize.width
-                    let hasEnoughHeight = frame.size.height - translation.y >= realMinimumSize.height
-
-                    let xPossibleTranslation = hasEnoughWidth ? translation.x : 0
-                    let yPossibleTranslation = hasEnoughHeight ? translation.y : 0
-
-                    newFrame = CGRect(x: frame.origin.x + xPossibleTranslation,
-                                      y: frame.origin.y + yPossibleTranslation,
-                                      width: frame.size.width - xPossibleTranslation,
-                                      height: frame.size.height - yPossibleTranslation)
-                case buttons[1]:    // Top Right
-                    let hasEnoughWidth = frame.size.width + translation.x >= realMinimumSize.width
-                    let hasEnoughHeight = frame.size.height - translation.y >= realMinimumSize.height
-
-                    let xPossibleTranslation = hasEnoughWidth ? translation.x : 0
-                    let yPossibleTranslation = hasEnoughHeight ? translation.y : 0
-
-                    newFrame = CGRect(x: frame.origin.x,
-                                      y: frame.origin.y + yPossibleTranslation,
-                                      width: frame.size.width + xPossibleTranslation,
-                                      height: frame.size.height - yPossibleTranslation)
-                case buttons[2]:    // Bottom Left
-                    let hasEnoughWidth = frame.size.width - translation.x >= realMinimumSize.width
-                    let hasEnoughHeight = frame.size.height + translation.y >= realMinimumSize.height
-
-                    let xPossibleTranslation = hasEnoughWidth ? translation.x : 0
-                    let yPossibleTranslation = hasEnoughHeight ? translation.y : 0
-
-                    newFrame = CGRect(x: frame.origin.x + xPossibleTranslation,
-                                      y: frame.origin.y,
-                                      width: frame.size.width - xPossibleTranslation,
-                                      height: frame.size.height + yPossibleTranslation)
-                case buttons[3]:    // Bottom Right
-                    let hasEnoughWidth = frame.size.width + translation.x >= realMinimumSize.width
-                    let hasEnoughHeight = frame.size.height + translation.y >= realMinimumSize.height
-
-                    let xPossibleTranslation = hasEnoughWidth ? translation.x : 0
-                    let yPossibleTranslation = hasEnoughHeight ? translation.y : 0
-
-                    newFrame = CGRect(x: frame.origin.x,
-                                      y: frame.origin.y,
-                                      width: frame.size.width + xPossibleTranslation,
-                                      height: frame.size.height + yPossibleTranslation)
-                default:
-                    newFrame = CGRect.zero
-                }
-
-                let minimumFrame = CGRect(x: newFrame.origin.x,
-                                          y: newFrame.origin.y,
-                                          width: max(newFrame.size.width,
-                                                     minimumSize.width + 2 * outterGap),
-                                          height: max(newFrame.size.height,
-                                                      minimumSize.height + 2 * outterGap))
-
-                gestureRecognizer.setTranslation(CGPoint.zero, in: self)
-                
-                delegate?.didMoveCropOverlay(newFrame: minimumFrame)
-            }
-        } else if isMovable {
-            if gestureRecognizer.state == .began || gestureRecognizer.state == .changed {
-                let translation = gestureRecognizer.translation(in: self)
-
-                let newFrame = CGRect(x: frame.origin.x + translation.x,
-                                      y: frame.origin.y + translation.y,
-                                      width: frame.size.width,
-                                      height: frame.size.height)
-
-                gestureRecognizer.setTranslation(CGPoint.zero, in: self)
-
-                delegate?.didMoveCropOverlay(newFrame: newFrame)
-            }
-        }
-    }
-}

+ 0 - 149
Pods/ALCameraViewController/README.md

@@ -1,149 +0,0 @@
-# ALCameraViewController
-A camera view controller with custom image picker and image cropping.
-
-![camera](https://cloud.githubusercontent.com/assets/932822/8455694/c61de812-2006-11e5-85c0-a57e3d980561.jpg)
-![cropper](https://cloud.githubusercontent.com/assets/932822/8455697/c627ac44-2006-11e5-82be-7f96e73d9b1f.jpg)
-![library](https://cloud.githubusercontent.com/assets/932822/8455695/c620ebb6-2006-11e5-9c61-75a81870c9de.jpg)
-![permissions](https://cloud.githubusercontent.com/assets/932822/8455696/c62157fe-2006-11e5-958f-849cabf541ca.jpg)
-
-### Features
-
-- [x] Front facing and rear facing camera
-- [x] Simple and clean look
-- [x] Custom image picker with permission checking
-- [x] Image cropping
-- [x] Flash light
-- [x] Zoom
-- [x] Tap to focus
-
-### Installation & Requirements
-This project requires Xcode 9 to run and compiles with swift 4
-> Note: This library makes use of the AVFoundation camera API's which are unavailable on the iOS simulator. You'll need a real device to run it.
-
-CocoaPods:
-Add the following to your Podfile:
-
-```ruby
-pod 'ALCameraViewController'
-```
-> For swift 3.2 support
-
-```ruby
-pod 'ALCameraViewController', '~> 2.0.3'
-```
-
-Carthage:
-
-```ruby
-github "alexlittlejohn/ALCameraViewController"
-```
-
-
-### Privacy (iOS 10) ###
-If you are building your app with iOS 10 or newer, you need to add two privacy keys to your app to allow the usage of the camera and photo library, or your app will crash.
-
-Add the keys below to your `Info.plist`, adding strings with the description you want to provide when prompting the user.
-
-```
-    NSPhotoLibraryUsageDescription
-    NSCameraUsageDescription
-```
-
-### Usage
-
-To use this component couldn't be simpler.
-Add `import ALCameraViewController` to the top of your controller file.
-
-In the viewController
-```swift
-
-let cameraViewController = CameraViewController { [weak self] image, asset in
-	// Do something with your image here.
-	self?.dismiss(animated: true, completion: nil)
-}
-
-present(cameraViewController, animated: true, completion: nil)
-```
-
-### Parameters
-
-There are a number of configurable options available for `CameraViewController`
-
-```swift
-init(croppingParameters: CroppingParameters = CroppingParameters(),
-     allowsLibraryAccess: Bool = true,
-     allowsSwapCameraOrientation: Bool = true,
-     allowVolumeButtonCapture: Bool = true,
-     completion: @escaping CameraViewCompletion)
-```
-
-The Cropping Parameters struct accepts the following parameters
-
-```swift
-init(isEnabled: Bool = false,
-     allowResizing: Bool = true,
-     allowMoving: Bool = true,
-     minimumSize: CGSize = CGSize(width: 60, height: 60))
-```
-
-The success parameter returns a `UIImage?` and a `PHAsset?` for more advanced use cases.
-If the user canceled photo capture then both of these options will be `nil`
-
-```swift
-typealias CameraViewCompletion = (UIImage?, PHAsset?) -> Void
-```
-> Note: To prevent retain cycles, it is best to use a `[weak self]` reference within the success parameter
-
-### Other usage options
-
-You can also instantiate the image picker component by itself as well.
-```swift
-
-let croppingEnabled = true
-
-/// Provides an image picker wrapped inside a UINavigationController instance
-let imagePickerViewController = CameraViewController.imagePickerViewController(croppingEnabled: croppingEnabled) { [weak self] image, asset in
-		// Do something with your image here.
-	 	// If cropping is enabled this image will be the cropped version
-
-    self?.dismiss(animated: true, completion: nil)
-}
-
-present(imagePickerViewController, animated: true, completion: nil)
-
-```
-
-For more control you can create it directly.
-> Note: This approach requires some familiarity with the PhotoKit library provided by apple
-
-```swift
-import Photos
-
-let imagePickerViewController = PhotoLibraryViewController()
-imagePickerViewController.onSelectionComplete = { asset in
-
-		// The asset could be nil if the user doesn't select anything
-		guard let asset = asset else {
-			return
-		}
-
-    // Provides a PHAsset object
-		// Retrieve a UIImage from a PHAsset using
-		let options = PHImageRequestOptions()
-    options.deliveryMode = .highQualityFormat
-    options.isNetworkAccessAllowed = true
-
-		PHImageManager.default().requestImage(for: asset, targetSize: PHImageManagerMaximumSize, contentMode: .aspectFill, options: options) { image, _ in
-        if let image = image {
-						// Do something with your image here
-        }
-    }
-}
-
-present(imagePickerViewController, animated: true, completion: nil)
-
-```
-
-
-## License
-ALCameraViewController is available under the MIT license. See the LICENSE file for more info.

+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraView.strings → Pods/KK-ALCameraViewController/ALCameraViewController/CameraView.strings


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/Contents.json → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/Contents.json


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/cameraButton.imageset/Contents.json → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/cameraButton.imageset/Contents.json


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/cameraButton.imageset/cameraButton.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/cameraButton.imageset/cameraButton.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/cameraButton.imageset/cameraButton@2x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/cameraButton.imageset/cameraButton@2x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/cameraButton.imageset/cameraButton@3x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/cameraButton.imageset/cameraButton@3x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/cameraButtonHighlighted.imageset/Contents.json → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/cameraButtonHighlighted.imageset/Contents.json


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/cameraButtonHighlighted.imageset/cameraButtonHighlighted.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/cameraButtonHighlighted.imageset/cameraButtonHighlighted.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/cameraButtonHighlighted.imageset/cameraButtonHighlighted@2x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/cameraButtonHighlighted.imageset/cameraButtonHighlighted@2x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/cameraButtonHighlighted.imageset/cameraButtonHighlighted@3x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/cameraButtonHighlighted.imageset/cameraButtonHighlighted@3x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/closeButton.imageset/Contents.json → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/closeButton.imageset/Contents.json


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/closeButton.imageset/closeButton.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/closeButton.imageset/closeButton.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/closeButton.imageset/closeButton@2x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/closeButton.imageset/closeButton@2x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/closeButton.imageset/closeButton@3x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/closeButton.imageset/closeButton@3x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/confirmButton.imageset/Contents.json → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/confirmButton.imageset/Contents.json


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/confirmButton.imageset/confirmButton.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/confirmButton.imageset/confirmButton.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/confirmButton.imageset/confirmButton@2x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/confirmButton.imageset/confirmButton@2x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/confirmButton.imageset/confirmButton@3x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/confirmButton.imageset/confirmButton@3x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashAutoIcon.imageset/Contents.json → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashAutoIcon.imageset/Contents.json


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashAutoIcon.imageset/flashAutoIcon.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashAutoIcon.imageset/flashAutoIcon.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashAutoIcon.imageset/flashAutoIcon@2x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashAutoIcon.imageset/flashAutoIcon@2x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashAutoIcon.imageset/flashAutoIcon@3x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashAutoIcon.imageset/flashAutoIcon@3x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashOffIcon.imageset/Contents.json → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashOffIcon.imageset/Contents.json


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashOffIcon.imageset/flashOffIcon.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashOffIcon.imageset/flashOffIcon.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashOffIcon.imageset/flashOffIcon@2x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashOffIcon.imageset/flashOffIcon@2x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashOffIcon.imageset/flashOffIcon@3x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashOffIcon.imageset/flashOffIcon@3x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashOnIcon.imageset/Contents.json → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashOnIcon.imageset/Contents.json


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashOnIcon.imageset/flashOnIcon.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashOnIcon.imageset/flashOnIcon.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashOnIcon.imageset/flashOnIcon@2x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashOnIcon.imageset/flashOnIcon@2x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashOnIcon.imageset/flashOnIcon@3x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/flashOnIcon.imageset/flashOnIcon@3x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryButton.imageset/Contents.json → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryButton.imageset/Contents.json


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryButton.imageset/libraryButton.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryButton.imageset/libraryButton.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryButton.imageset/libraryButton@2x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryButton.imageset/libraryButton@2x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryButton.imageset/libraryButton@3x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryButton.imageset/libraryButton@3x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryCancel.imageset/Contents.json → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryCancel.imageset/Contents.json


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryCancel.imageset/libraryCancel.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryCancel.imageset/libraryCancel.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryCancel.imageset/libraryCancel@2x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryCancel.imageset/libraryCancel@2x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryCancel.imageset/libraryCancel@3x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryCancel.imageset/libraryCancel@3x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryConfirm.imageset/Contents.json → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryConfirm.imageset/Contents.json


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryConfirm.imageset/libraryConfirm.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryConfirm.imageset/libraryConfirm.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryConfirm.imageset/libraryConfirm@2x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryConfirm.imageset/libraryConfirm@2x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryConfirm.imageset/libraryConfirm@3x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/libraryConfirm.imageset/libraryConfirm@3x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/permissionsIcon.imageset/Contents.json → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/permissionsIcon.imageset/Contents.json


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/permissionsIcon.imageset/cameraPermissionsIcon.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/permissionsIcon.imageset/cameraPermissionsIcon.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/permissionsIcon.imageset/cameraPermissionsIcon@2x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/permissionsIcon.imageset/cameraPermissionsIcon@2x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/permissionsIcon.imageset/cameraPermissionsIcon@3x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/permissionsIcon.imageset/cameraPermissionsIcon@3x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/placeholder.imageset/Contents.json → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/placeholder.imageset/Contents.json


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/placeholder.imageset/placeholder.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/placeholder.imageset/placeholder.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/placeholder.imageset/placeholder@2x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/placeholder.imageset/placeholder@2x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/placeholder.imageset/placeholder@3x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/placeholder.imageset/placeholder@3x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/retakeButton.imageset/Contents.json → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/retakeButton.imageset/Contents.json


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/retakeButton.imageset/retakeButton.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/retakeButton.imageset/retakeButton.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/retakeButton.imageset/retakeButton@2x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/retakeButton.imageset/retakeButton@2x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/retakeButton.imageset/retakeButton@3x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/retakeButton.imageset/retakeButton@3x.png


+ 23 - 0
Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/rotateButton.imageset/Contents.json

@@ -0,0 +1,23 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "filename" : "rotateButton@1x.png",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "rotateButton@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "rotateButton@3x.png",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}

BIN
Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/rotateButton.imageset/rotateButton@1x.png


BIN
Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/rotateButton.imageset/rotateButton@2x.png


BIN
Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/rotateButton.imageset/rotateButton@3x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/swapButton.imageset/Contents.json → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/swapButton.imageset/Contents.json


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/swapButton.imageset/swapButton.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/swapButton.imageset/swapButton.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/swapButton.imageset/swapButton@2x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/swapButton.imageset/swapButton@2x.png


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/swapButton.imageset/swapButton@3x.png → Pods/KK-ALCameraViewController/ALCameraViewController/CameraViewAssets.xcassets/swapButton.imageset/swapButton@3x.png


+ 56 - 0
Pods/KK-ALCameraViewController/ALCameraViewController/Utilities/CameraGlobals.swift

@@ -0,0 +1,56 @@
+//
+//  CameraGlobals.swift
+//  ALCameraViewController
+//
+//  Created by Alex Littlejohn on 2016/02/16.
+//  Copyright © 2016 zero. All rights reserved.
+//
+//  Modified by Kevin Kieffer on 2019/08/06.  Changes as follows:
+//  Adding adjustable number of columns for library view, based on .ipad or smaller device
+
+
+
+import UIKit
+import AVFoundation
+
+internal let itemSpacing: CGFloat = 1
+internal let scale = UIScreen.main.scale
+
+public class CameraGlobals {
+    public static let shared = CameraGlobals()
+    
+    public var bundle = Bundle(for: CameraViewController.self)
+    public var stringsTable = "CameraView"
+    public var defaultCameraPosition = AVCaptureDevice.Position.back
+    
+    public static let MAX_COLUMNS : Int = {
+        switch UIDevice.current.userInterfaceIdiom {
+        case .pad:
+            return 20
+        default:
+            return 10
+        }
+    }()
+    
+    public static let MIN_COLUMNS = 2
+    
+    public static let DEFAULT_COLUMNS : Int = {
+        switch UIDevice.current.userInterfaceIdiom {
+        case .pad:
+            return 8
+        default:
+            return 4
+        }
+    }()
+    
+      
+    public func photoLibraryThumbnailSize(withColumns columns : Int) -> CGSize {
+        
+        let cols = CGFloat(columns)
+        let thumbnailDimension = (UIScreen.main.bounds.width - ((cols * itemSpacing) - itemSpacing))/cols
+        return CGSize(width: thumbnailDimension, height: thumbnailDimension)
+            
+        
+    }
+    
+}

+ 1 - 1
Pods/ALCameraViewController/ALCameraViewController/Utilities/CameraShot.swift → Pods/KK-ALCameraViewController/ALCameraViewController/Utilities/CameraShot.swift

@@ -49,7 +49,7 @@ public func takePhoto(_ stillImageOutput: AVCaptureStillImageOutput, videoOrient
             case .downMirrored:
                 image = UIImage(cgImage: cgImage, scale: image.scale, orientation: .down)
             @unknown default:
-                break
+                fatalError("unknown image orientation")
             }
         }
         

+ 65 - 0
Pods/KK-ALCameraViewController/ALCameraViewController/Utilities/CroppingParameters.swift

@@ -0,0 +1,65 @@
+//
+//  CroppingParameters.swift
+//  ALCameraViewController
+//
+//  Created by Guillaume Bellut on 02/09/2017.
+//  Copyright © 2017 zero. All rights reserved.
+//
+//  Modified by Kevin Kieffer on 2019/08/06.  Changes as follows:
+//  Adding an aspectRatio for the cropping rectangle. Default is 1 (a square)
+
+
+import UIKit
+
+public struct CroppingParameters {
+
+    /// Enable the cropping feature.
+    /// Default value is set to false.
+    let isEnabled: Bool
+    
+    /// Enable the overlay on the camera feature
+    /// Default is set to true
+    let cameraOverlay : Bool
+
+    /// Allow the cropping area to be resized by the user.
+    /// Default value is set to true.
+    let allowResizing: Bool
+
+    /// Allow the cropping area to be moved by the user.
+    /// Default value is set to false.
+    let allowMoving: Bool
+    
+    
+    /// Allow rotating 90 degrees in the confirm view
+    /// Default value is set to true
+    let allowRotate: Bool
+    
+    /// Aspect ratio of the crop
+    let aspectRatioHeightToWidth : CGFloat
+
+    /// Prevent the user to resize the cropping area below a minimum size.
+    /// Default value is (60, 60). Below this value, corner buttons will overlap.
+    let minimumSize: CGSize
+    
+    /// The maximum scale factor the user can zoom in, default of 1
+    let maximumZoom : CGFloat
+
+    public init(isEnabled: Bool = false,
+                allowResizing: Bool = true,
+                allowMoving: Bool = true,
+                allowRotate: Bool = true,
+         minimumSize: CGSize = CGSize(width: 60, height: 60),
+         aspectRatioHeightToWidth: CGFloat = 1.0,
+         maximumZoom: CGFloat = 1.0,
+         cameraOverlay : Bool = true) {
+
+        self.isEnabled = isEnabled
+        self.allowResizing = allowResizing
+        self.allowMoving = allowMoving
+        self.allowRotate = allowRotate
+        self.minimumSize = minimumSize
+        self.aspectRatioHeightToWidth = aspectRatioHeightToWidth
+        self.maximumZoom = maximumZoom
+        self.cameraOverlay = cameraOverlay
+    }
+}

+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/Utilities/ImageFetcher.swift → Pods/KK-ALCameraViewController/ALCameraViewController/Utilities/ImageFetcher.swift


+ 2 - 1
Pods/ALCameraViewController/ALCameraViewController/Utilities/PhotoLibraryAuthorizer.swift → Pods/KK-ALCameraViewController/ALCameraViewController/Utilities/PhotoLibraryAuthorizer.swift

@@ -43,7 +43,8 @@ class PhotoLibraryAuthorizer {
             }
             break
         @unknown default:
-            break
+             let error = errorWithKey("error.unknown-auth-status", domain: errorDomain)
+             completion(error)
         }
     }
 }

+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/Utilities/SingleImageFetcher.swift → Pods/KK-ALCameraViewController/ALCameraViewController/Utilities/SingleImageFetcher.swift


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/Utilities/SingleImageSaver.swift → Pods/KK-ALCameraViewController/ALCameraViewController/Utilities/SingleImageSaver.swift


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/Utilities/UIButtonExtensions.swift → Pods/KK-ALCameraViewController/ALCameraViewController/Utilities/UIButtonExtensions.swift


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/Utilities/UIViewExtensions.swift → Pods/KK-ALCameraViewController/ALCameraViewController/Utilities/UIViewExtensions.swift


+ 3 - 8
Pods/ALCameraViewController/ALCameraViewController/Utilities/Utilities.swift → Pods/KK-ALCameraViewController/ALCameraViewController/Utilities/Utilities.swift

@@ -54,12 +54,7 @@ internal func currentRotation(_ oldOrientation: UIInterfaceOrientation, newOrien
     }
 }
 
-internal func largestPhotoSize() -> CGSize {
-    let scale = UIScreen.main.scale
-    let screenSize = UIScreen.main.bounds.size
-    let size = CGSize(width: screenSize.width * scale, height: screenSize.height * scale)
-    return size
-}
+
 
 internal func errorWithKey(_ key: String, domain: String) -> NSError {
     let errorString = localizedString(key)
@@ -87,7 +82,7 @@ internal func normalizedRect(_ rect: CGRect, orientation: UIImage.Orientation) -
     case .right, .rightMirrored:
         normalizedRect = CGRect(x: normalizedY, y: 1-normalizedX-normalizedWidth, width: normalizedHeight, height: normalizedWidth)
     @unknown default:
-        normalizedRect = .zero
+        fatalError("unknown orientation")
     }
     
     return normalizedRect
@@ -103,7 +98,7 @@ internal func flashImage(_ mode: AVCaptureDevice.FlashMode) -> String {
     case .off:
         image = "flashOffIcon"
     @unknown default:
-        image = "flashOffIcon"
+        fatalError("unknown flash mode")
     }
     return image
 }

+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/Utilities/VolumeControl.swift → Pods/KK-ALCameraViewController/ALCameraViewController/Utilities/VolumeControl.swift


+ 58 - 56
Pods/ALCameraViewController/ALCameraViewController/ViewController/CameraViewController.swift → Pods/KK-ALCameraViewController/ALCameraViewController/ViewController/CameraViewController.swift

@@ -5,6 +5,11 @@
 //  Created by Alex Littlejohn.
 //  Copyright (c) 2016 zero. All rights reserved.
 //
+//  Modified by Kevin Kieffer on 2019/08/06.  Changes as follows:
+//  Update the overlay constraints when rotating, so the overlay is properly positioned and sized
+//
+//  Updated the button constraint calls and removed the rotate animation method which was not working
+
 
 import UIKit
 import AVFoundation
@@ -33,6 +38,7 @@ public extension CameraViewController {
                     }
                 }
                 confirmController.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
+                confirmController.modalPresentationStyle = .fullScreen
                 imagePicker?.present(confirmController, animated: true, completion: nil)
             } else {
                 completion(nil, nil)
@@ -78,12 +84,24 @@ open class CameraViewController: UIViewController {
     
     var flashButtonEdgeConstraint: NSLayoutConstraint?
     var flashButtonGravityConstraint: NSLayoutConstraint?
-
+    
+    var cameraOverlayEdgeOneConstraint: NSLayoutConstraint?
+    var cameraOverlayEdgeTwoConstraint: NSLayoutConstraint?
+    var cameraOverlayWidthConstraint: NSLayoutConstraint?
+    var cameraOverlayCenterConstraint: NSLayoutConstraint?
+    
     let cameraView : CameraView = {
         let cameraView = CameraView()
         cameraView.translatesAutoresizingMaskIntoConstraints = false
         return cameraView
     }()
+
+    let cameraOverlay : CropOverlay = {
+        let cameraOverlay = CropOverlay()
+        cameraOverlay.translatesAutoresizingMaskIntoConstraints = false
+        cameraOverlay.showsButtons = false
+        return cameraOverlay
+    }()
     
     let cameraButton : UIButton = {
         let button = UIButton(frame: CGRect(x: 0, y: 0, width: 64, height: 64))
@@ -159,6 +177,8 @@ open class CameraViewController: UIViewController {
         self.allowVolumeButtonCapture = allowVolumeButtonCapture
         super.init(nibName: nil, bundle: nil)
         onCompletion = completion
+        cameraOverlay.isHidden = !croppingParameters.isEnabled || !croppingParameters.cameraOverlay
+        cameraOverlay.isUserInteractionEnabled = false
         libraryButton.isEnabled = allowsLibraryAccess
         libraryButton.isHidden = !allowsLibraryAccess
 		swapButton.isEnabled = allowsSwapCameraOrientation
@@ -186,6 +206,7 @@ open class CameraViewController: UIViewController {
         super.loadView()
         view.backgroundColor = UIColor.black
         [cameraView,
+            cameraOverlay,
             cameraButton,
             closeButton,
             flashButton,
@@ -194,6 +215,16 @@ open class CameraViewController: UIViewController {
         view.setNeedsUpdateConstraints()
     }
     
+    private func updateOverlayConstraints() {
+        let portrait = UIApplication.shared.statusBarOrientation.isPortrait
+        let padding : CGFloat = portrait ? 16.0 : -16.0
+        removeCameraOverlayEdgesConstraints()
+        configCameraOverlayEdgeOneContraint(portrait, padding: padding)
+        configCameraOverlayEdgeTwoConstraint(portrait, padding: padding)
+        configCameraOverlayWidthConstraint(portrait)
+        configCameraOverlayCenterConstraint(portrait)
+    }
+    
     /**
      * Setup the constraints when the app is starting or rotating
      * the screen.
@@ -211,7 +242,8 @@ open class CameraViewController: UIViewController {
         
         let statusBarOrientation = UIApplication.shared.statusBarOrientation
         let portrait = statusBarOrientation.isPortrait
-        
+
+        removeCameraButtonConstraints()
         configCameraButtonEdgeConstraint(statusBarOrientation)
         configCameraButtonGravityConstraint(portrait)
         
@@ -225,17 +257,17 @@ open class CameraViewController: UIViewController {
         
         removeSwapButtonConstraints()
         configSwapButtonEdgeConstraint(statusBarOrientation)
-        configSwapButtonGravityConstraint(portrait)
+        configSwapButtonGravityConstraint(statusBarOrientation)
 
         removeLibraryButtonConstraints()
         configLibraryEdgeButtonConstraint(statusBarOrientation)
-        configLibraryGravityButtonConstraint(portrait)
+        configLibraryGravityButtonConstraint(statusBarOrientation)
         
         configFlashEdgeButtonConstraint(statusBarOrientation)
         configFlashGravityButtonConstraint(statusBarOrientation)
-
-        rotate(actualInterfaceOrientation: statusBarOrientation)
         
+        updateOverlayConstraints()
+         
         super.updateViewConstraints()
     }
     
@@ -252,7 +284,15 @@ open class CameraViewController: UIViewController {
         super.viewDidLoad()
         setupActions()
         checkPermissions()
+        cameraView.configureFocus()
         cameraView.configureZoom()
+        
+        if let device = AVCaptureDevice.default(for: .video) {
+            if !device.hasFlash {
+                flashButton.isEnabled = false
+                flashButton.isHidden = true
+            }
+        }
     }
 
     /**
@@ -372,57 +412,10 @@ open class CameraViewController: UIViewController {
     
     @objc func rotateCameraView() {
         cameraView.rotatePreview()
+        updateViewConstraints()
     }
     
-    /**
-     * This method will rotate the buttons based on
-     * the last and actual orientation of the device.
-     */
-    internal func rotate(actualInterfaceOrientation: UIInterfaceOrientation) {
-        
-        if lastInterfaceOrientation != nil {
-            let lastTransform = CGAffineTransform(rotationAngle: radians(currentRotation(
-                lastInterfaceOrientation!, newOrientation: actualInterfaceOrientation)))
-            setTransform(transform: lastTransform)
-        }
-
-        let transform = CGAffineTransform(rotationAngle: 0)
-        animationRunning = true
-        
-        /**
-         * Dispatch delay to avoid any conflict between the CATransaction of rotation of the screen
-         * and CATransaction of animation of buttons.
-         */
-
-        let duration = animationDuration
-        let spring = animationSpring
-        let options = rotateAnimation
-
-        let time: DispatchTime = DispatchTime.now() + Double(1 * UInt64(NSEC_PER_SEC)/10)
-        DispatchQueue.main.asyncAfter(deadline: time) { [weak self] in
-
-            guard let _ = self else {
-                return
-            }
-            
-            CATransaction.begin()
-            CATransaction.setDisableActions(false)
-            CATransaction.commit()
-            
-            UIView.animate(
-                withDuration: duration,
-                delay: 0.1,
-                usingSpringWithDamping: spring,
-                initialSpringVelocity: 0,
-                options: options,
-                animations: { [weak self] in
-                self?.setTransform(transform: transform)
-                }, completion: { [weak self] _ in
-                    self?.animationRunning = false
-            })
-            
-        }
-    }
+    
     
     func setTransform(transform: CGAffineTransform) {
         closeButton.transform = transform
@@ -575,11 +568,15 @@ open class CameraViewController: UIViewController {
 		let confirmViewController = ConfirmViewController(image: uiImage, croppingParameters: croppingParameters)
 		confirmViewController.onComplete = { [weak self] image, asset in
 			defer {
+                //In iOS13, the volume changed notification channel is being called when dismissing this controller
+                //Since this controller comes back into view momentarily here, before being dismissed, another
+                //photo is being taken and the camera shutter sound occurs. As a workaround, the volume control
+                //is deinitialized here to remove the notification channel.
+                self?.volumeControl = nil
 				self?.dismiss(animated: true, completion: nil)
 			}
 			
 			guard let image = image else {
-				self?.cameraView.startSession()
 				return
 			}
 			
@@ -587,6 +584,8 @@ open class CameraViewController: UIViewController {
 			self?.onCompletion = nil
 		}
 		confirmViewController.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
+        confirmViewController.modalPresentationStyle = .fullScreen
+
 		present(confirmViewController, animated: true, completion: nil)
 	}
 	
@@ -594,6 +593,7 @@ open class CameraViewController: UIViewController {
         let confirmViewController = ConfirmViewController(asset: asset, croppingParameters: croppingParameters)
         confirmViewController.onComplete = { [weak self] image, asset in
             defer {
+                self?.volumeControl = nil
                 self?.dismiss(animated: true, completion: nil)
             }
 
@@ -605,6 +605,8 @@ open class CameraViewController: UIViewController {
             self?.onCompletion = nil
         }
         confirmViewController.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
+        confirmViewController.modalPresentationStyle = .fullScreen
+
         present(confirmViewController, animated: true, completion: nil)
     }
 

+ 129 - 22
Pods/ALCameraViewController/ALCameraViewController/ViewController/CameraViewControllerConstraint.swift → Pods/KK-ALCameraViewController/ALCameraViewController/ViewController/CameraViewControllerConstraint.swift

@@ -5,6 +5,12 @@
 //  Created by Pedro Paulo de Amorim.
 //  Copyright (c) 2016 zero. All rights reserved.
 //
+//  Modified by Kevin Kieffer on 2019/08/06.  Changes as follows:
+//  Changed configCameraOverlayWidthConstraint() to use a multipler to provide a rectangle instead of a square,
+//  the rectangle being created by using an aspect ratio from the CroppingParameters
+//
+//  Cleaned up the constraints for the flash, swap, and library buttons to work properly in both landscape orientations
+
 
 import UIKit
 import AVFoundation
@@ -35,6 +41,11 @@ extension CameraViewController {
         })
     }
     
+    func removeCameraButtonConstraints() {
+        view.autoRemoveConstraint(cameraButtonEdgeConstraint)
+        view.autoRemoveConstraint(cameraButtonGravityConstraint)
+    }
+    
     /**
      * Add the constraints based on the device orientation,
      * this pin the button on the bottom part of the screen
@@ -42,16 +53,17 @@ extension CameraViewController {
      * the button on the right part of the screen.
      */
     func configCameraButtonEdgeConstraint(_ statusBarOrientation: UIInterfaceOrientation) {
-        view.autoRemoveConstraint(cameraButtonEdgeConstraint)
         
         let attribute : NSLayoutConstraint.Attribute = {
             switch statusBarOrientation {
-            case .portrait: return .bottomMargin
-            case .landscapeRight: return .rightMargin
-            case .landscapeLeft: return .leftMargin
-            default: return .topMargin
+            case .portrait: return .bottom
+            case .landscapeRight: return .right
+            case .landscapeLeft: return .left
+            default: return .top
             }
         }()
+        let constraintPortrait = statusBarOrientation == .portrait || statusBarOrientation == .landscapeRight
+
         
         cameraButtonEdgeConstraint = NSLayoutConstraint(
             item: cameraButton,
@@ -60,7 +72,8 @@ extension CameraViewController {
             toItem: view,
             attribute: attribute,
             multiplier: 1.0,
-            constant: -8)
+            constant: constraintPortrait ? -16 : 16)
+        
         view.addConstraint(cameraButtonEdgeConstraint!)
     }
     
@@ -71,7 +84,6 @@ extension CameraViewController {
      * the button based on the height of screen.
      */
     func configCameraButtonGravityConstraint(_ portrait: Bool) {
-        view.autoRemoveConstraint(cameraButtonGravityConstraint)
         let attribute : NSLayoutConstraint.Attribute = portrait ? .centerX : .centerY
         cameraButtonGravityConstraint = NSLayoutConstraint(
             item: cameraButton,
@@ -227,15 +239,19 @@ extension CameraViewController {
      * Configure the center of SwapButton, based on the
      * axis center of CameraButton.
      */
-    func configSwapButtonGravityConstraint(_ portrait: Bool) {
+    func configSwapButtonGravityConstraint(_ statusBarOrientation: UIInterfaceOrientation) {
+        
+        let portrait = statusBarOrientation == .portrait
+        let landLeft = statusBarOrientation == .landscapeLeft
+        
         swapButtonGravityConstraint = NSLayoutConstraint(
             item: swapButton,
-            attribute: portrait ? .right : .bottom,
-            relatedBy: .lessThanOrEqual,
+            attribute: portrait ? .right : (landLeft ? .bottom : .top),
+            relatedBy: portrait || landLeft ? .lessThanOrEqual : .greaterThanOrEqual,
             toItem: containerSwapLibraryButton,
             attribute: portrait ? .centerX : .centerY,
             multiplier: 1.0,
-            constant: -4.0 * DeviceConfig.SCREEN_MULTIPLIER)
+            constant: (portrait || landLeft ? -4.0 : 4.0) * DeviceConfig.SCREEN_MULTIPLIER)
         view.addConstraint(swapButtonGravityConstraint!)
     }
     
@@ -379,15 +395,19 @@ extension CameraViewController {
      * Set the center gravity of the LibraryButton based
      * on the position of CameraButton.
      */
-    func configLibraryGravityButtonConstraint(_ portrait: Bool) {
+    func configLibraryGravityButtonConstraint(_ statusBarOrientation: UIInterfaceOrientation) {
+        
+        let portrait = statusBarOrientation == .portrait
+        let landLeft = statusBarOrientation == .landscapeLeft
+        
         libraryButtonGravityConstraint = NSLayoutConstraint(
             item: libraryButton,
-            attribute: portrait ? .left : .top,
-            relatedBy: .lessThanOrEqual,
+            attribute: portrait ? .left : (landLeft ? .top : .bottom),
+            relatedBy: portrait || landLeft ? .greaterThanOrEqual : .lessThanOrEqual,
             toItem: containerSwapLibraryButton,
             attribute: portrait ? .centerX : .centerY,
             multiplier: 1.0,
-            constant: 4.0 * DeviceConfig.SCREEN_MULTIPLIER)
+            constant: (portrait || landLeft ? 4.0 : -4.0) * DeviceConfig.SCREEN_MULTIPLIER)
         view.addConstraint(libraryButtonGravityConstraint!)
     }
     
@@ -400,8 +420,8 @@ extension CameraViewController {
     func configFlashEdgeButtonConstraint(_ statusBarOrientation: UIInterfaceOrientation) {
         view.autoRemoveConstraint(flashButtonEdgeConstraint)
         
-        let constraintRight = statusBarOrientation == .portrait || statusBarOrientation == .landscapeRight
-        let attribute : NSLayoutConstraint.Attribute = constraintRight ? .topMargin : .bottomMargin
+        let constraintPortrait = statusBarOrientation == .portrait || statusBarOrientation == .landscapeLeft
+        let attribute : NSLayoutConstraint.Attribute = constraintPortrait ? .top : .left
         
         flashButtonEdgeConstraint = NSLayoutConstraint(
             item: flashButton,
@@ -410,7 +430,7 @@ extension CameraViewController {
             toItem: view,
             attribute: attribute,
             multiplier: 1.0,
-            constant: constraintRight ? 8 : -8)
+            constant: constraintPortrait ? 16 : 16)
         view.addConstraint(flashButtonEdgeConstraint!)
     }
     
@@ -424,8 +444,8 @@ extension CameraViewController {
     func configFlashGravityButtonConstraint(_ statusBarOrientation: UIInterfaceOrientation) {
         view.autoRemoveConstraint(flashButtonGravityConstraint)
         
-        let constraintRight = statusBarOrientation == .portrait || statusBarOrientation == .landscapeLeft
-        let attribute : NSLayoutConstraint.Attribute = constraintRight ? .right : .left
+        let constraintPortrait = statusBarOrientation == .portrait || statusBarOrientation == .landscapeLeft
+        let attribute : NSLayoutConstraint.Attribute = constraintPortrait ? .right : .top
         
         flashButtonGravityConstraint = NSLayoutConstraint(
             item: flashButton,
@@ -434,8 +454,95 @@ extension CameraViewController {
             toItem: view,
             attribute: attribute,
             multiplier: 1.0,
-            constant: constraintRight ? -8 : 8)
+            constant: constraintPortrait ? -16 : 16)
         view.addConstraint(flashButtonGravityConstraint!)
     }
-
+    
+    /**
+     * Used to create a perfect was: square now: rectangle with aspect ratio for CameraOverlay.
+     * This method will determinate the size of CameraOverlay,
+     * if portrait, it will use the width of superview to
+     * determinate the height of the view. Else if landscape,
+     * it uses the height of the superview to create the width
+     * of the CameraOverlay.
+     */
+    func configCameraOverlayWidthConstraint(_ portrait: Bool) {
+        view.autoRemoveConstraint(cameraOverlayWidthConstraint)
+        cameraOverlayWidthConstraint = NSLayoutConstraint(
+            item: cameraOverlay,
+            attribute: portrait ? .height : .width,
+            relatedBy: .equal,
+            toItem: cameraOverlay,
+            attribute: portrait ? .width : .height,
+            multiplier: portrait ? croppingParameters.aspectRatioHeightToWidth : 1.0/croppingParameters.aspectRatioHeightToWidth,
+            constant: 0)
+        view.addConstraint(cameraOverlayWidthConstraint!)
+    }
+    
+    /**
+     * This method will center the relative position of
+     * CameraOverlay, based on the biggest size of the
+     * superview.
+     */
+    func configCameraOverlayCenterConstraint(_ portrait: Bool) {
+        view.autoRemoveConstraint(cameraOverlayCenterConstraint)
+        let attribute : NSLayoutConstraint.Attribute = portrait ? .centerY : .centerX
+        cameraOverlayCenterConstraint = NSLayoutConstraint(
+            item: cameraOverlay,
+            attribute: attribute,
+            relatedBy: .equal,
+            toItem: view,
+            attribute: attribute,
+            multiplier: 1.0,
+            constant: 0)
+        view.addConstraint(cameraOverlayCenterConstraint!)
+    }
+    
+    /**
+     * Remove the CameraOverlay constraints to be updated when
+     * the device was rotated.
+     */
+    func removeCameraOverlayEdgesConstraints() {
+        view.autoRemoveConstraint(cameraOverlayEdgeOneConstraint)
+        view.autoRemoveConstraint(cameraOverlayEdgeTwoConstraint)
+    }
+    
+    /**
+     * It needs to get a determined smallest size of the screen
+     to create the smallest size to be used on CameraOverlay.
+     It uses the orientation of the screen to determinate where
+     the view will be pinned.
+     */
+    func configCameraOverlayEdgeOneContraint(_ portrait: Bool, padding: CGFloat) {
+        let attribute : NSLayoutConstraint.Attribute = portrait ? .left : .bottom
+        cameraOverlayEdgeOneConstraint = NSLayoutConstraint(
+            item: cameraOverlay,
+            attribute: attribute,
+            relatedBy: .equal,
+            toItem: view,
+            attribute: attribute,
+            multiplier: 1.0,
+            constant: padding)
+        view.addConstraint(cameraOverlayEdgeOneConstraint!)
+    }
+    
+    /**
+     * It needs to get a determined smallest size of the screen
+     to create the smallest size to be used on CameraOverlay.
+     It uses the orientation of the screen to determinate where
+     the view will be pinned.
+     */
+    func configCameraOverlayEdgeTwoConstraint(_ portrait: Bool, padding: CGFloat) {
+        let attributeTwo : NSLayoutConstraint.Attribute = portrait ? .right : .top
+        cameraOverlayEdgeTwoConstraint = NSLayoutConstraint(
+            item: cameraOverlay,
+            attribute: attributeTwo,
+            relatedBy: .equal,
+            toItem: view,
+            attribute: attributeTwo,
+            multiplier: 1.0,
+            constant: -padding)
+        view.addConstraint(cameraOverlayEdgeTwoConstraint!)
+    }
+    
 }

+ 500 - 0
Pods/KK-ALCameraViewController/ALCameraViewController/ViewController/ConfirmViewController.swift

@@ -0,0 +1,500 @@
+//
+//  ALConfirmViewController.swift
+//  ALCameraViewController
+//
+//  Created by Alex Littlejohn on 2015/06/30.
+//  Copyright (c) 2015 zero. All rights reserved.
+//
+//
+//  Modified by Kevin Kieffer on 2019/08/06.  Changes as follows:  significantly updated the operation of this
+//  class because as far as I could determine the subviews were not arranging themselves properly when the
+//  device was rotated. Simplified this class by removing the centeringView and scrollView insets, and simply centering the
+//  scrollView in the overall view, setting the scrollView content size = imageView frame size, and centering the cropOverlay
+//  over the scrollView whenever the view finished laying out its subviews.
+//
+//  Furthermore minimum scrollView zoom size was set based on the crop rectangle, but the initial view was set to fully
+//  fit the image on the screen.
+//
+//  A new aspectRatio constraint was created and all constraints were removed from the cropOverlay view in the .xib file.
+//  The centeringView was also removed from the .xib file and the Confirm and Cancel buttons were moved closer to the edge.
+//
+//  A center touch point is set on the CropOverlay if the CropParameters say its movable
+//
+//  Lastly, the image cropping worked differently if the crop rectangle was out of the image bounds, depending on whether
+//  the image came from a PHAsset or a UIImage. In the former, the crop maintained the aspect ratio of the crop rectangle
+//  (possibly distorting the image), but in the latter, it truncated the crop rectangle to the bounds of the image, changing
+//  the aspect ratio.  Since maintaining the aspect ratio is preferred, a change to the UIImage extension was made to rescale the
+//  cropped image back to the aspect ratio, which also possibly distorts the image but preserves the aspect ratio.
+
+
+
+
+import UIKit
+import Photos
+
+public class ConfirmViewController: UIViewController, UIScrollViewDelegate {
+	
+    var CROP_PADDING : CGFloat {
+        switch UIDevice.current.userInterfaceIdiom {
+        case .pad:
+            return CGFloat(120)
+        default:
+            return CGFloat(30)
+        }
+    }
+    
+	let imageView = UIImageView()
+    
+    @IBOutlet weak var scrollView: UIScrollView!
+    @IBOutlet weak var cropOverlay: CropOverlay!
+    @IBOutlet weak var confirmButton: UIButton!
+    @IBOutlet weak var cancelButton: UIButton!
+    @IBOutlet weak var rotateButton: UIButton!
+    
+    
+    
+    var croppingParameters: CroppingParameters {
+        didSet {
+            cropOverlay.showsCenterPoint = croppingParameters.allowMoving
+            cropOverlay.isResizable = croppingParameters.allowResizing
+            cropOverlay.isMovable = croppingParameters.allowMoving
+            cropOverlay.minimumSize = croppingParameters.minimumSize
+            cropOverlay.showsButtons = croppingParameters.allowResizing
+        }
+    }
+
+	public var onComplete: CameraViewCompletion?
+
+	let asset: PHAsset?
+	let image: UIImage?
+	
+    var didInitialAdjustCropOverlay = false
+    var didInitialCenterCropOverlay = false
+
+	public init(image: UIImage, croppingParameters: CroppingParameters) {
+		self.croppingParameters = croppingParameters
+		self.asset = nil
+		self.image = image
+		super.init(nibName: "ConfirmViewController", bundle: CameraGlobals.shared.bundle)
+	}
+	
+	public init(asset: PHAsset, croppingParameters: CroppingParameters) {
+		self.croppingParameters = croppingParameters
+		self.asset = asset
+		self.image = nil
+		super.init(nibName: "ConfirmViewController", bundle: CameraGlobals.shared.bundle)
+	}
+	
+    public required init?(coder aDecoder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+	}
+	
+    deinit {
+        NotificationCenter.default.removeObserver(self)
+    }
+    
+	public override var prefersStatusBarHidden: Bool {
+		return true
+	}
+	
+	public override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
+		return UIStatusBarAnimation.slide
+	}
+	
+	public override func viewDidLoad() {
+		super.viewDidLoad()
+
+		view.backgroundColor = UIColor.black
+		
+		scrollView.addSubview(imageView)
+		scrollView.delegate = self
+		scrollView.maximumZoomScale = croppingParameters.maximumZoom
+		
+        cropOverlay.showsCenterPoint = croppingParameters.allowMoving
+        cropOverlay.isHidden = true
+        cropOverlay.isResizable = croppingParameters.allowResizing
+        cropOverlay.isMovable = croppingParameters.allowMoving
+        cropOverlay.minimumSize = croppingParameters.minimumSize
+        cropOverlay.showsButtons = croppingParameters.allowResizing
+
+        if !croppingParameters.allowRotate {
+            rotateButton.isHidden = true
+        }
+        
+		let spinner = showSpinner()
+		
+		disable()
+		
+		if let asset = asset {  //load full resolution image size
+			_ = SingleImageFetcher()
+				.setAsset(asset)
+				.onSuccess { [weak self] image in
+					self?.configureWithImage(image)
+					self?.hideSpinner(spinner)
+					self?.enable()
+				}
+				.onFailure { [weak self] error in
+					self?.hideSpinner(spinner)
+				}
+				.fetch()
+		} else if let image = image {
+			configureWithImage(image)
+			hideSpinner(spinner)
+			enable()
+		}
+        
+        NotificationCenter.default.addObserver(self, selector: #selector(orientationChanged), name:  Notification.Name("UIDeviceOrientationDidChangeNotification"), object: nil)
+
+	}
+    
+    @objc func orientationChanged() {
+        centerCropFrame()
+    }
+	
+    public override func viewWillLayoutSubviews() {
+        
+        if !didInitialAdjustCropOverlay || !cropOverlay.isResizable {
+            adjustCropOverlay()  //keep it centered and constrainted on orientation changes
+            didInitialAdjustCropOverlay = true
+        }
+        
+    }
+	
+    public override func viewDidLayoutSubviews() {
+        super.viewDidLayoutSubviews()
+        
+        
+        let (minscale, initscale) = calculateMinimumAndInitialScale()
+        
+        scrollView.contentSize = imageView.frame.size
+        scrollView.minimumZoomScale = minscale
+        scrollView.zoomScale = initscale
+
+        self.centerScrollViewContents()
+        
+        if !cropOverlay.isResizable || !didInitialCenterCropOverlay {
+            self.centerCropFrame()
+            didInitialCenterCropOverlay = true
+        }
+        
+    }
+    
+    private func adjustCropOverlay() {
+        switch UIDevice.current.orientation {
+        case .landscapeLeft, .landscapeRight:
+            cropOverlay.frame.size.height = view.frame.height - CROP_PADDING  //height is constrained in landscale
+            cropOverlay.frame.size.width = cropOverlay.frame.size.height / croppingParameters.aspectRatioHeightToWidth
+        default:
+             cropOverlay.frame.size.width = view.frame.width - CROP_PADDING //width is constrained in portrait
+             cropOverlay.frame.size.height = cropOverlay.frame.size.width * croppingParameters.aspectRatioHeightToWidth
+        }
+    }
+	
+	private func configureWithImage(_ image: UIImage) {
+		cropOverlay.isHidden = !croppingParameters.isEnabled
+		
+		buttonActions()
+		
+		imageView.image = image
+		imageView.sizeToFit()
+		view.setNeedsLayout()
+	}
+	
+    
+    //Returns a tuple containing the minimum scale and the desired initial scale of the scroll view
+	private func calculateMinimumAndInitialScale() -> (CGFloat, CGFloat) {
+        guard let image = imageView.image else {
+            return (1,1)
+        }
+    
+        //The initial scale will fit the entire image on the screen in either orientation
+        let size = view.bounds
+        let scaleWidth = size.width / image.size.width
+        let scaleHeight = size.height / image.size.height
+    
+        let minSizeWithoutCrop = min(scaleWidth, scaleHeight)
+    
+    
+        //If cropping enabled, the minimum scale fits the image into the crop rectangle, otherwise
+        //its the same as in the initial scale
+		if croppingParameters.isEnabled {
+            
+            let cropSize = cropOverlay.frame.size
+            let cropScaleWidth = (cropSize.width - CROP_PADDING) / image.size.width
+            let cropScaleHeight = (cropSize.height - CROP_PADDING) / image.size.height
+            
+            let minSizeWithCrop = min(cropScaleWidth, cropScaleHeight)
+    
+            return (minSizeWithCrop, minSizeWithoutCrop)
+		}
+        else {
+            return (minSizeWithoutCrop, minSizeWithoutCrop)
+        }
+		
+	}
+	
+	private func calculateScrollViewInsets(_ frame: CGRect) -> UIEdgeInsets {
+		let bottom = view.frame.height - (frame.origin.y + frame.height)
+		let right = view.frame.width - (frame.origin.x + frame.width)
+		let insets = UIEdgeInsets(top: frame.origin.y, left: frame.origin.x, bottom: bottom, right: right)
+		return insets
+	}
+	
+	private func centerImageViewOnRotate() {
+		if croppingParameters.isEnabled {
+			let size = cropOverlay.frame.size
+			let scrollInsets = scrollView.contentInset
+			let imageSize = imageView.frame.size
+			var contentOffset = CGPoint(x: -scrollInsets.left, y: -scrollInsets.top)
+			contentOffset.x -= (size.width - imageSize.width) / 2
+			contentOffset.y -= (size.height - imageSize.height) / 2
+			scrollView.contentOffset = contentOffset
+		}
+	}
+	
+    private func centerCropFrame() {
+        let size = scrollView.frame.size
+        let cropSize = cropOverlay.frame.size
+        var origin = CGPoint.zero
+        
+        if cropSize.width < size.width {
+            origin.x = (size.width - cropSize.width) / 2
+        }
+        
+        if cropSize.height < size.height {
+            origin.y = (size.height - cropSize.height) / 2
+        }
+        
+        cropOverlay.frame.origin = origin
+    }
+    
+	private func centerScrollViewContents() {
+		let size = scrollView.frame.size
+		let imageSize = imageView.frame.size
+		var imageOrigin = CGPoint.zero
+		
+		if imageSize.width < size.width {
+			imageOrigin.x = (size.width - imageSize.width) / 2
+		}
+		
+		if imageSize.height < size.height {
+			imageOrigin.y = (size.height - imageSize.height) / 2
+		}
+		
+		imageView.frame.origin = imageOrigin
+	}
+	
+	private func buttonActions() {
+		confirmButton.action = { [weak self] in self?.confirmPhoto() }
+		cancelButton.action = { [weak self] in self?.cancel() }
+        rotateButton.action = { [weak self] in self?.rotateRight() }
+	}
+    
+    internal func rotateRight() {
+        if let rotatedImage = imageView.image?.rotate() {
+            configureWithImage(rotatedImage)
+            centerScrollViewContents()
+        }
+    }
+	
+	internal func cancel() {
+        cropOverlay.removeFromSuperview()  //remove overlay while processing
+		onComplete?(nil, nil)
+	}
+	
+	internal func confirmPhoto() {
+		
+		guard let image = imageView.image else {
+			return
+		}
+		
+		disable()
+		
+		imageView.isHidden = true
+		
+		let spinner = showSpinner()
+		        
+        if croppingParameters.isEnabled {
+            let cropRect = makeProportionalCropRect()
+            let resizedCropRect = CGRect(x: (image.size.width) * cropRect.origin.x,
+                                 y: (image.size.height) * cropRect.origin.y,
+                                 width: (image.size.width * cropRect.width),
+                                 height: (image.size.height * cropRect.height))
+            
+            DispatchQueue.global(qos: .userInitiated).async {
+                let croppedImage = image.crop(rect: resizedCropRect)  //This can take long time and block UI
+                DispatchQueue.main.async {
+                    self.onComplete?(croppedImage, self.asset)
+                    self.hideSpinner(spinner)
+                }
+            }
+            
+        }
+        else {
+            onComplete?(image, self.asset)
+            hideSpinner(spinner)
+        }
+		
+        cropOverlay.removeFromSuperview()  //remove overlay while processing
+	}
+	
+	public func viewForZooming(in scrollView: UIScrollView) -> UIView? {
+		return imageView
+	}
+	
+	public func scrollViewDidZoom(_ scrollView: UIScrollView) {
+		centerScrollViewContents()
+	}
+    
+    
+    override public func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
+        view.setNeedsLayout()
+    }
+	
+	func showSpinner() -> UIActivityIndicatorView {
+		let spinner = UIActivityIndicatorView()
+        spinner.style = .white
+		spinner.center = view.center
+		spinner.startAnimating()
+		
+		view.addSubview(spinner)
+        view.bringSubviewToFront(spinner)
+		
+		return spinner
+	}
+	
+	func hideSpinner(_ spinner: UIActivityIndicatorView) {
+		spinner.stopAnimating()
+		spinner.removeFromSuperview()
+	}
+	
+	func disable() {
+		confirmButton.isEnabled = false
+        cancelButton.isEnabled = false
+	}
+	
+	func enable() {
+		confirmButton.isEnabled = true
+        cancelButton.isEnabled = true
+	}
+	
+	func showNoImageScreen(_ error: NSError) {
+		let permissionsView = PermissionsView(frame: view.bounds)
+		
+		let desc = localizedString("error.cant-fetch-photo.description")
+		
+		permissionsView.configureInView(view, title: error.localizedDescription, description: desc, completion: { [weak self] in self?.cancel() })
+	}
+	
+	private func makeProportionalCropRect() -> CGRect {
+		var cropRect = CGRect(x: cropOverlay.frame.origin.x + cropOverlay.outterGap,
+		                      y: cropOverlay.frame.origin.y + cropOverlay.outterGap,
+		                      width: cropOverlay.frame.size.width - 2 * cropOverlay.outterGap,
+		                      height: cropOverlay.frame.size.height - 2 * cropOverlay.outterGap)
+        
+        cropRect.origin.x += scrollView.contentOffset.x - imageView.frame.origin.x
+        cropRect.origin.y += scrollView.contentOffset.y - imageView.frame.origin.y
+
+		let normalizedX = cropRect.origin.x / imageView.frame.width
+		let normalizedY = cropRect.origin.y / imageView.frame.height
+
+        let extraWidth = CGFloat(0) //fabs(cropRect.origin.x)
+        let extraHeight = CGFloat(0) //fabs(cropRect.origin.y)
+
+		let normalizedWidth = (cropRect.width + extraWidth) / imageView.frame.width
+		let normalizedHeight = (cropRect.height + extraHeight) / imageView.frame.height
+		
+		return CGRect(x: normalizedX, y: normalizedY, width: normalizedWidth, height: normalizedHeight)
+	}
+	
+}
+
+extension UIImage {
+    
+	func crop(rect: CGRect) -> UIImage {
+
+		var rectTransform: CGAffineTransform
+		switch imageOrientation {
+		case .left:
+			rectTransform = CGAffineTransform(rotationAngle: radians(90)).translatedBy(x: 0, y: -size.height)
+		case .right:
+			rectTransform = CGAffineTransform(rotationAngle: radians(-90)).translatedBy(x: -size.width, y: 0)
+		case .down:
+			rectTransform = CGAffineTransform(rotationAngle: radians(-180)).translatedBy(x: -size.width, y: -size.height)
+		default:
+			rectTransform = CGAffineTransform.identity
+		}
+		
+		rectTransform = rectTransform.scaledBy(x: scale, y: scale)
+		
+        let cropAspect = rect.height / rect.width
+        
+        if let cropped = cgImage?.cropping(to: rect.applying(rectTransform)) {
+            
+			let cropImage = UIImage(cgImage: cropped, scale: scale, orientation: imageOrientation).fixOrientation()
+            
+            
+            //Rescale the cropped portion to maintain the crop aspect ratio
+            let currentAspect = cropImage.size.height / cropImage.size.width
+                        
+            return cropImage.scaledBy(size: CGSize(width: cropImage.size.width, height: cropImage.size.height * cropAspect / currentAspect)) ?? self
+            
+           
+        }
+		
+		return self
+	}
+	
+	func fixOrientation() -> UIImage {
+		if imageOrientation == .up {
+			return self
+		}
+		
+		UIGraphicsBeginImageContextWithOptions(size, false, scale)
+		draw(in: CGRect(origin: .zero, size: size))
+		let normalizedImage: UIImage = UIGraphicsGetImageFromCurrentImageContext() ?? self
+		UIGraphicsEndImageContext()
+		
+		return normalizedImage
+	}
+    
+    func scaledBy(size: CGSize) -> UIImage? {
+        let hasAlpha = false
+        let scale: CGFloat = 0.0 // Automatically use scale factor of main screen
+        
+        UIGraphicsBeginImageContextWithOptions(size, !hasAlpha, scale)
+        self.draw(in: CGRect(origin: CGPoint(x: 0, y: 0), size: size))
+        
+        let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
+        UIGraphicsEndImageContext()
+        
+        return scaledImage
+    }
+    
+    //Rotate by 90 degrees
+    func rotate() -> UIImage? {
+        
+        let radians = Float.pi/2
+        
+        var newSize = CGRect(origin: CGPoint.zero, size: CGSize(width: self.size.width, height: self.size.height)).applying(CGAffineTransform(rotationAngle: CGFloat(radians))).size
+        
+        // Trim off the extremely small float value to prevent core graphics from rounding it up
+        newSize.width = floor(newSize.width)
+        newSize.height = floor(newSize.height)
+
+        UIGraphicsBeginImageContextWithOptions(newSize, false, self.scale)
+        let context = UIGraphicsGetCurrentContext()!
+        
+        // Move origin to middle
+        context.translateBy(x: newSize.width/2, y: newSize.height/2)
+        // Rotate around middle
+        context.rotate(by: CGFloat(radians))
+        // Draw the image at its center
+        self.draw(in: CGRect(x: -self.size.width/2, y: -self.size.height/2, width: self.size.width, height: self.size.height))
+
+        let newImage = UIGraphicsGetImageFromCurrentImageContext()
+        UIGraphicsEndImageContext()
+
+        return newImage
+    }
+}

+ 37 - 67
Pods/ALCameraViewController/ALCameraViewController/ViewController/ConfirmViewController.xib → Pods/KK-ALCameraViewController/ALCameraViewController/ViewController/ConfirmViewController.xib

@@ -1,41 +1,52 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15400" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
-    <device id="retina4_0" orientation="portrait" appearance="light"/>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina5_9" orientation="portrait" appearance="light"/>
     <dependencies>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15404"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
         <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ConfirmViewController" customModule="ALCameraViewController" customModuleProvider="target">
             <connections>
                 <outlet property="cancelButton" destination="yRi-ES-LfN" id="PUm-mc-H7R"/>
-                <outlet property="centeredView" destination="KYd-D9-K5d" id="CmX-BA-VtZ"/>
                 <outlet property="confirmButton" destination="ASf-ZD-cIs" id="mpH-Eg-IbA"/>
+                <outlet property="cropOverlay" destination="lnA-tb-Sap" id="34E-zk-Axd"/>
+                <outlet property="rotateButton" destination="Wyb-8e-TYr" id="3T7-ex-gnO"/>
                 <outlet property="scrollView" destination="oUR-U3-uEM" id="rF0-ZM-RmA"/>
                 <outlet property="view" destination="iN0-l3-epB" id="FcS-Dy-kqF"/>
             </connections>
         </placeholder>
         <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
         <view contentMode="scaleToFill" id="iN0-l3-epB">
-            <rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
+            <rect key="frame" x="0.0" y="0.0" width="375" height="812"/>
             <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
             <subviews>
                 <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="oUR-U3-uEM">
-                    <rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
+                    <rect key="frame" x="0.0" y="0.0" width="375" height="812"/>
                 </scrollView>
-                <view userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="KYd-D9-K5d">
-                    <rect key="frame" x="0.0" y="0.0" width="320" height="464"/>
+                <view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="lnA-tb-Sap" customClass="CropOverlay" customModule="ALCameraViewController" customModuleProvider="target">
+                    <rect key="frame" x="15" y="195" width="345" height="309"/>
+                    <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                    <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
                 </view>
                 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ASf-ZD-cIs">
-                    <rect key="frame" x="20" y="484" width="64" height="64"/>
+                    <rect key="frame" x="101.66666666666669" y="732" width="64" height="64"/>
                     <constraints>
                         <constraint firstAttribute="height" constant="64" id="J7n-mn-Ebe"/>
                         <constraint firstAttribute="width" constant="64" id="YWt-e6-Bvy"/>
                     </constraints>
                     <state key="normal" image="confirmButton"/>
                 </button>
+                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Wyb-8e-TYr">
+                    <rect key="frame" x="303" y="8" width="64" height="64"/>
+                    <constraints>
+                        <constraint firstAttribute="width" constant="64" id="B5T-2l-ykm"/>
+                        <constraint firstAttribute="height" constant="64" id="dPw-t7-uXu"/>
+                    </constraints>
+                    <state key="normal" image="rotateButton"/>
+                </button>
                 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="yRi-ES-LfN">
-                    <rect key="frame" x="236" y="484" width="64" height="64"/>
+                    <rect key="frame" x="225.66666666666663" y="732" width="64" height="64"/>
                     <constraints>
                         <constraint firstAttribute="height" constant="64" id="FdJ-mW-Tx6"/>
                         <constraint firstAttribute="width" constant="64" id="urS-JS-i1S"/>
@@ -45,64 +56,36 @@
             </subviews>
             <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
             <constraints>
-                <constraint firstItem="ASf-ZD-cIs" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" id="1AT-7k-2QI"/>
-                <constraint firstAttribute="trailing" secondItem="oUR-U3-uEM" secondAttribute="trailing" id="7A6-HH-MEu"/>
-                <constraint firstAttribute="bottom" secondItem="yRi-ES-LfN" secondAttribute="bottom" constant="20" id="7jo-lC-34t"/>
+                <constraint firstAttribute="bottom" secondItem="yRi-ES-LfN" secondAttribute="bottom" constant="16" id="7jo-lC-34t"/>
                 <constraint firstItem="ASf-ZD-cIs" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" constant="-45" id="89L-rE-rmd"/>
-                <constraint firstAttribute="bottom" secondItem="oUR-U3-uEM" secondAttribute="bottom" id="8mU-82-Hf6"/>
-                <constraint firstItem="oUR-U3-uEM" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="92s-g3-wfK"/>
-                <constraint firstItem="KYd-D9-K5d" firstAttribute="leading" secondItem="yRi-ES-LfN" secondAttribute="trailing" id="CcA-mG-BLU"/>
-                <constraint firstItem="yRi-ES-LfN" firstAttribute="top" secondItem="KYd-D9-K5d" secondAttribute="bottom" constant="20" id="Ck2-xk-HbG"/>
-                <constraint firstItem="oUR-U3-uEM" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="Cuy-cw-jOk"/>
-                <constraint firstAttribute="bottom" secondItem="ASf-ZD-cIs" secondAttribute="bottom" constant="20" id="DZ5-WA-3ZQ"/>
+                <constraint firstAttribute="bottom" secondItem="ASf-ZD-cIs" secondAttribute="bottom" constant="16" id="DZ5-WA-3ZQ"/>
                 <constraint firstAttribute="bottom" secondItem="yRi-ES-LfN" secondAttribute="bottom" constant="60" id="H4a-3r-r5r"/>
+                <constraint firstItem="Wyb-8e-TYr" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="8" id="IAo-1m-56l"/>
                 <constraint firstItem="oUR-U3-uEM" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="J3N-Vr-euu"/>
-                <constraint firstAttribute="trailing" secondItem="KYd-D9-K5d" secondAttribute="trailing" id="JLk-PT-5kn"/>
-                <constraint firstAttribute="trailing" secondItem="yRi-ES-LfN" secondAttribute="trailing" constant="20" id="M7P-T7-qoy"/>
-                <constraint firstItem="ASf-ZD-cIs" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="30" id="Rwi-4K-QRb"/>
+                <constraint firstItem="ASf-ZD-cIs" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="16" id="Rwi-4K-QRb"/>
                 <constraint firstItem="ASf-ZD-cIs" firstAttribute="bottom" secondItem="yRi-ES-LfN" secondAttribute="top" constant="-60" id="TLl-L0-yLb"/>
-                <constraint firstAttribute="trailing" secondItem="KYd-D9-K5d" secondAttribute="trailing" id="YBv-2a-KdQ"/>
-                <constraint firstItem="KYd-D9-K5d" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="Yhb-Y3-ngX"/>
-                <constraint firstItem="KYd-D9-K5d" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="aj9-Xh-WHL"/>
-                <constraint firstItem="KYd-D9-K5d" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="hPp-8q-A1p"/>
-                <constraint firstItem="ASf-ZD-cIs" firstAttribute="top" secondItem="KYd-D9-K5d" secondAttribute="bottom" id="iar-0y-gBe"/>
+                <constraint firstItem="ASf-ZD-cIs" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" constant="-54" id="WSF-pa-4wb"/>
+                <constraint firstAttribute="trailing" secondItem="Wyb-8e-TYr" secondAttribute="trailing" constant="8" id="hZW-wp-wrm"/>
                 <constraint firstAttribute="bottom" secondItem="oUR-U3-uEM" secondAttribute="bottom" id="iw9-Cg-Kkk"/>
                 <constraint firstItem="oUR-U3-uEM" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="kDN-mM-6KE"/>
+                <constraint firstItem="yRi-ES-LfN" firstAttribute="leading" secondItem="ASf-ZD-cIs" secondAttribute="trailing" constant="60" id="m1F-XR-hgU"/>
                 <constraint firstAttribute="trailing" secondItem="oUR-U3-uEM" secondAttribute="trailing" id="mL3-PM-TEd"/>
-                <constraint firstAttribute="bottom" secondItem="KYd-D9-K5d" secondAttribute="bottom" id="o6j-Qo-hB5"/>
                 <constraint firstItem="ASf-ZD-cIs" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" constant="-54" id="pNU-uB-Igt"/>
-                <constraint firstItem="yRi-ES-LfN" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="30" id="v0q-tU-ywG"/>
-                <constraint firstItem="KYd-D9-K5d" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="vnU-ey-3GX"/>
-                <constraint firstAttribute="trailing" secondItem="KYd-D9-K5d" secondAttribute="trailing" id="wTn-DN-uQO"/>
-                <constraint firstItem="KYd-D9-K5d" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="wn3-We-BBK"/>
+                <constraint firstItem="yRi-ES-LfN" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="16" id="v0q-tU-ywG"/>
                 <constraint firstItem="yRi-ES-LfN" firstAttribute="top" secondItem="ASf-ZD-cIs" secondAttribute="top" id="xFS-1L-oa4"/>
                 <constraint firstItem="yRi-ES-LfN" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" constant="45" id="xFc-F1-V7I"/>
             </constraints>
             <variation key="default">
                 <mask key="constraints">
-                    <exclude reference="CcA-mG-BLU"/>
-                    <exclude reference="JLk-PT-5kn"/>
-                    <exclude reference="YBv-2a-KdQ"/>
-                    <exclude reference="Yhb-Y3-ngX"/>
-                    <exclude reference="aj9-Xh-WHL"/>
-                    <exclude reference="hPp-8q-A1p"/>
-                    <exclude reference="o6j-Qo-hB5"/>
-                    <exclude reference="vnU-ey-3GX"/>
-                    <exclude reference="wTn-DN-uQO"/>
-                    <exclude reference="wn3-We-BBK"/>
-                    <exclude reference="7A6-HH-MEu"/>
-                    <exclude reference="8mU-82-Hf6"/>
-                    <exclude reference="92s-g3-wfK"/>
-                    <exclude reference="Cuy-cw-jOk"/>
                     <exclude reference="89L-rE-rmd"/>
                     <exclude reference="DZ5-WA-3ZQ"/>
                     <exclude reference="Rwi-4K-QRb"/>
                     <exclude reference="TLl-L0-yLb"/>
-                    <exclude reference="iar-0y-gBe"/>
+                    <exclude reference="WSF-pa-4wb"/>
                     <exclude reference="pNU-uB-Igt"/>
                     <exclude reference="7jo-lC-34t"/>
-                    <exclude reference="Ck2-xk-HbG"/>
                     <exclude reference="H4a-3r-r5r"/>
+                    <exclude reference="m1F-XR-hgU"/>
                     <exclude reference="v0q-tU-ywG"/>
                     <exclude reference="xFS-1L-oa4"/>
                     <exclude reference="xFc-F1-V7I"/>
@@ -110,13 +93,9 @@
             </variation>
             <variation key="heightClass=compact">
                 <mask key="subviews">
-                    <include reference="KYd-D9-K5d"/>
+                    <include reference="lnA-tb-Sap"/>
                 </mask>
                 <mask key="constraints">
-                    <include reference="CcA-mG-BLU"/>
-                    <include reference="Yhb-Y3-ngX"/>
-                    <include reference="o6j-Qo-hB5"/>
-                    <include reference="wTn-DN-uQO"/>
                     <include reference="Rwi-4K-QRb"/>
                     <include reference="TLl-L0-yLb"/>
                     <include reference="pNU-uB-Igt"/>
@@ -125,38 +104,29 @@
             </variation>
             <variation key="heightClass=regular-widthClass=compact">
                 <mask key="subviews">
-                    <include reference="KYd-D9-K5d"/>
+                    <include reference="lnA-tb-Sap"/>
                 </mask>
                 <mask key="constraints">
-                    <include reference="JLk-PT-5kn"/>
-                    <include reference="aj9-Xh-WHL"/>
-                    <include reference="wn3-We-BBK"/>
                     <include reference="DZ5-WA-3ZQ"/>
+                    <include reference="WSF-pa-4wb"/>
                     <include reference="7jo-lC-34t"/>
-                    <include reference="Ck2-xk-HbG"/>
+                    <include reference="m1F-XR-hgU"/>
                 </mask>
             </variation>
             <variation key="heightClass=regular-widthClass=regular">
                 <mask key="constraints">
-                    <include reference="YBv-2a-KdQ"/>
-                    <include reference="hPp-8q-A1p"/>
-                    <include reference="vnU-ey-3GX"/>
-                    <include reference="7A6-HH-MEu"/>
-                    <include reference="8mU-82-Hf6"/>
-                    <include reference="92s-g3-wfK"/>
-                    <include reference="Cuy-cw-jOk"/>
                     <include reference="89L-rE-rmd"/>
-                    <include reference="iar-0y-gBe"/>
                     <include reference="H4a-3r-r5r"/>
                     <include reference="xFS-1L-oa4"/>
                     <include reference="xFc-F1-V7I"/>
                 </mask>
             </variation>
-            <point key="canvasLocation" x="131" y="154"/>
+            <point key="canvasLocation" x="133.59999999999999" y="74.630541871921181"/>
         </view>
     </objects>
     <resources>
         <image name="confirmButton" width="44" height="44"/>
         <image name="retakeButton" width="44" height="44"/>
+        <image name="rotateButton" width="44" height="44"/>
     </resources>
 </document>

+ 41 - 1
Pods/ALCameraViewController/ALCameraViewController/ViewController/PhotoLibraryViewController.swift → Pods/KK-ALCameraViewController/ALCameraViewController/ViewController/PhotoLibraryViewController.swift

@@ -5,6 +5,9 @@
 //  Created by Alex Littlejohn on 2015/06/09.
 //  Copyright (c) 2015 zero. All rights reserved.
 //
+//  Modified by Kevin Kieffer on 2019/08/06.  Changes as follows:
+//  Adding a pinch gesture to increase or decrease the number of columns shown, up to a min or max value
+
 
 import UIKit
 import Photos
@@ -19,12 +22,14 @@ public class PhotoLibraryViewController: UIViewController {
     
     internal var assets: PHFetchResult<PHAsset>? = nil
     
+    private var columns = CameraGlobals.DEFAULT_COLUMNS
+    
     public var onSelectionComplete: PhotoLibraryViewSelectionComplete?
     
     private lazy var collectionView: UICollectionView = {
         let layout = UICollectionViewFlowLayout()
         
-        layout.itemSize = CameraGlobals.shared.photoLibraryThumbnailSize
+        layout.itemSize = CameraGlobals.shared.photoLibraryThumbnailSize(withColumns: columns)
         layout.minimumInteritemSpacing = defaultItemSpacing
         layout.minimumLineSpacing = defaultItemSpacing
         layout.sectionInset = UIEdgeInsets.zero
@@ -54,6 +59,9 @@ public class PhotoLibraryViewController: UIViewController {
             .onFailure(onFailure)
             .onSuccess(onSuccess)
             .fetch()
+        
+        let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(pinch(gesture:)))
+        view.addGestureRecognizer(pinchGesture)
     }
     
     public override func viewWillLayoutSubviews() {
@@ -76,6 +84,31 @@ public class PhotoLibraryViewController: UIViewController {
         onSelectionComplete?(nil)
     }
     
+    
+    @objc internal func pinch(gesture: UIPinchGestureRecognizer) {
+        
+        
+        switch gesture.state {
+        case .began, .changed:
+            if gesture.scale > CGFloat(1.2) && columns > CameraGlobals.MIN_COLUMNS {
+                gesture.scale = CGFloat(1.0)
+                columns -= 1
+                collectionView.collectionViewLayout.invalidateLayout()
+            }
+            else if gesture.scale < CGFloat(0.8) && columns < CameraGlobals.MAX_COLUMNS {
+                gesture.scale = CGFloat(1.0)
+                columns += 1
+                collectionView.collectionViewLayout.invalidateLayout()
+            }
+        case .ended:
+            gesture.scale = CGFloat(1.0)
+        default:
+            break
+        }
+    }
+    
+    
+    
     private func onSuccess(_ photos: PHFetchResult<PHAsset>) {
         assets = photos
         configureCollectionView()
@@ -124,4 +157,11 @@ extension PhotoLibraryViewController : UICollectionViewDelegateFlowLayout {
     public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
         onSelectionComplete?(itemAtIndexPath(indexPath))
     }
+    
+    public func collectionView(_ collectionView: UICollectionView,
+                        layout collectionViewLayout: UICollectionViewLayout,
+                        sizeForItemAt indexPath: IndexPath) -> CGSize {
+        return CameraGlobals.shared.photoLibraryThumbnailSize(withColumns: columns)
+    }
+
 }

+ 63 - 2
Pods/ALCameraViewController/ALCameraViewController/Views/CameraView.swift → Pods/KK-ALCameraViewController/ALCameraViewController/Views/CameraView.swift

@@ -18,7 +18,9 @@ public class CameraView: UIView {
     var preview: AVCaptureVideoPreviewLayer!
     
     let cameraQueue = DispatchQueue(label: "com.zero.ALCameraViewController.Queue")
-
+    
+    let focusView = CropOverlay(frame: CGRect(x: 0, y: 0, width: 80, height: 80))
+    
     public var currentPosition = CameraGlobals.shared.defaultCameraPosition
     
     public func startSession() {
@@ -26,7 +28,12 @@ public class CameraView: UIView {
         session.sessionPreset = AVCaptureSession.Preset.photo
 
         device = cameraWithPosition(position: currentPosition)
-        if let device = device , device.hasFlash {
+        if device == nil {
+            print("Error: No Camera device found")
+            return
+        }
+        
+        if device.hasFlash {
             do {
                 try device.lockForConfiguration()
                 device.flashMode = .auto
@@ -79,11 +86,65 @@ public class CameraView: UIView {
         super.layoutSubviews()
         preview?.frame = bounds
     }
+    
+    public func configureFocus() {
+        
+        if let gestureRecognizers = gestureRecognizers {
+            gestureRecognizers.forEach({ removeGestureRecognizer($0) })
+        }
+        
+        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(focus(gesture:)))
+        addGestureRecognizer(tapGesture)
+        isUserInteractionEnabled = true
+        addSubview(focusView)
+        
+        focusView.isHidden = true
+        
+        let lines = focusView.horizontalLines + focusView.verticalLines + focusView.outerLines
+        
+        lines.forEach { line in
+            line.alpha = 0
+        }
+    }
 
     public func configureZoom() {
         let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(pinch(gesture:)))
         addGestureRecognizer(pinchGesture)
     }
+    
+    @objc internal func focus(gesture: UITapGestureRecognizer) {
+        let point = gesture.location(in: self)
+        
+        guard focusCamera(toPoint: point) else {
+            return
+        }
+        
+        focusView.isHidden = false
+        focusView.center = point
+        focusView.alpha = 0
+        focusView.transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
+        
+        bringSubviewToFront(focusView)
+        
+        UIView.animateKeyframes(withDuration: 1.5, delay: 0, options: UIView.KeyframeAnimationOptions(), animations: {
+            
+            UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.15, animations: { [weak self] in
+                self?.focusView.alpha = 1
+                self?.focusView.transform = CGAffineTransform.identity
+            })
+            
+            UIView.addKeyframe(withRelativeStartTime: 0.80, relativeDuration: 0.20, animations: { [weak self] in
+                self?.focusView.alpha = 0
+                self?.focusView.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
+            })
+            
+            
+            }, completion: { [weak self] finished in
+                if finished {
+                    self?.focusView.isHidden = true
+                }
+        })
+    }
 
     @objc internal func pinch(gesture: UIPinchGestureRecognizer) {
         guard let device = device else { return }

+ 287 - 0
Pods/KK-ALCameraViewController/ALCameraViewController/Views/CropOverlay.swift

@@ -0,0 +1,287 @@
+//
+//  CropOverlay.swift
+//  ALCameraViewController
+//
+//  Created by Alex Littlejohn on 2015/06/30.
+//  Copyright (c) 2015 zero. All rights reserved.
+//
+//  Modified by Kevin Kieffer on 2019/08/06.  Changes as follows:
+//  Added a center point circle that shows the touch point for moving the crop overlay. Previously, the user could move the
+//  overlay by dragging anywhere in the bounds, but this prevents pinch-resizing of the image except at the very edge.
+//  Here, the user must touch within the center point to move.  The resize corners still work as before.
+
+import UIKit
+
+internal class CropOverlay: UIView {
+
+    
+    private class CenterCircleView : UIView {
+        
+        override init(frame : CGRect) {
+            super.init(frame: frame)
+            contentMode = .redraw
+            backgroundColor = .clear
+            isOpaque = false
+        }
+        
+        required init?(coder aDecoder: NSCoder) {
+            fatalError("init(coder:) has not been implemented")
+        }
+        
+        override func draw(_ rect: CGRect) {
+            if let context = UIGraphicsGetCurrentContext() {
+                let radius = bounds.width/2 - 1.0  //account for stroke width
+                context.addArc(center: CGPoint(x: bounds.midX, y: bounds.midY), radius: radius, startAngle: 0, endAngle: 2*CGFloat.pi, clockwise: true)
+                
+                UIColor.blue.setStroke()
+                context.strokePath()
+            }
+        }
+        
+    }
+    
+    var outerLines = [UIView]()
+    var horizontalLines = [UIView]()
+    var verticalLines = [UIView]()
+    
+    private var centerCircle = CenterCircleView()
+
+    private var centerCircleRadius : CGFloat {
+        get {
+            let minSide = min(bounds.width, bounds.height)
+            return min(minSide, 34.0)
+        }
+    }
+    
+    var topLeftCornerLines = [UIView]()
+    var topRightCornerLines = [UIView]()
+    var bottomLeftCornerLines = [UIView]()
+    var bottomRightCornerLines = [UIView]()
+
+    var cornerButtons = [UIButton]()
+
+    let cornerLineDepth: CGFloat = 3
+    let cornerLineWidth: CGFloat = 22.5
+    var cornerButtonWidth: CGFloat {
+        return self.cornerLineWidth * 2
+    }
+
+    let lineWidth: CGFloat = 1
+
+    let outterGapRatio: CGFloat = 1/3
+    var outterGap: CGFloat {
+        return self.cornerButtonWidth * self.outterGapRatio
+    }
+
+    var isResizable: Bool = false
+    var isMovable: Bool = false
+    var showsCenterPoint = false
+    var showsButtons = true
+    var minimumSize: CGSize = CGSize.zero
+
+    internal override init(frame: CGRect) {
+        super.init(frame: frame)
+        createLines()
+        addSubview(centerCircle)
+  }
+
+    internal required init?(coder aDecoder: NSCoder) {
+        super.init(coder: aDecoder)
+        createLines()
+        addSubview(centerCircle)
+    }
+    
+    override func layoutSubviews() {
+        
+        for i in 0..<outerLines.count {
+            let line = outerLines[i]
+            var lineFrame: CGRect
+            switch (i) {
+            case 0:
+                lineFrame = CGRect(x: outterGap, y: outterGap, width: bounds.width - outterGap * 2, height: lineWidth)
+                break
+            case 1:
+                lineFrame = CGRect(x: bounds.width - lineWidth - outterGap, y: outterGap, width: lineWidth, height: bounds.height - outterGap * 2)
+                break
+            case 2:
+                lineFrame = CGRect(x: outterGap, y: bounds.height - lineWidth - outterGap, width: bounds.width - outterGap * 2, height: lineWidth)
+                break
+            case 3:
+                lineFrame = CGRect(x: outterGap, y: outterGap, width: lineWidth, height: bounds.height - outterGap * 2)
+                break
+            default:
+                lineFrame = CGRect.zero
+                break
+            }
+            
+            line.frame = lineFrame
+        }
+        
+        if showsCenterPoint {
+            let r = centerCircleRadius
+            centerCircle.frame = CGRect(x: bounds.midX - r, y: bounds.midY - r, width: r * 2, height: r * 2)
+            centerCircle.setNeedsDisplay()
+        }
+        
+        if showsButtons {
+            let corners = [topLeftCornerLines, topRightCornerLines, bottomLeftCornerLines, bottomRightCornerLines]
+            for i in 0..<corners.count {
+                let corner = corners[i]
+                
+                var horizontalFrame: CGRect
+                var verticalFrame: CGRect
+                var buttonFrame: CGRect
+                let buttonSize = CGSize(width: cornerButtonWidth, height: cornerButtonWidth)
+                
+                switch (i) {
+                case 0:	// Top Left
+                    verticalFrame = CGRect(x: outterGap, y: outterGap, width: cornerLineDepth, height: cornerLineWidth)
+                    horizontalFrame = CGRect(x: outterGap, y: outterGap, width: cornerLineWidth, height: cornerLineDepth)
+                    buttonFrame = CGRect(origin: CGPoint(x: 0, y: 0), size: buttonSize)
+                case 1:	// Top Right
+                    verticalFrame = CGRect(x: bounds.width - cornerLineDepth - outterGap, y: outterGap, width: cornerLineDepth, height: cornerLineWidth)
+                    horizontalFrame = CGRect(x: bounds.width - cornerLineWidth - outterGap, y: outterGap, width: cornerLineWidth, height: cornerLineDepth)
+                    buttonFrame = CGRect(origin: CGPoint(x: bounds.width - cornerButtonWidth, y: 0), size: buttonSize)
+                case 2:	// Bottom Left
+                    verticalFrame = CGRect(x: outterGap, y:  bounds.height - cornerLineWidth - outterGap, width: cornerLineDepth, height: cornerLineWidth)
+                    horizontalFrame = CGRect(x: outterGap, y:  bounds.height - cornerLineDepth - outterGap, width: cornerLineWidth, height: cornerLineDepth)
+                    buttonFrame = CGRect(origin: CGPoint(x: 0, y: bounds.height - cornerButtonWidth), size: buttonSize)
+                case 3:	// Bottom Right
+                    verticalFrame = CGRect(x: bounds.width - cornerLineDepth - outterGap, y: bounds.height - cornerLineWidth - outterGap, width: cornerLineDepth, height: cornerLineWidth)
+                    horizontalFrame = CGRect(x: bounds.width - cornerLineWidth - outterGap, y: bounds.height - cornerLineDepth - outterGap, width: cornerLineWidth, height: cornerLineDepth)
+                    buttonFrame = CGRect(origin: CGPoint(x: bounds.width - cornerButtonWidth, y: bounds.height - cornerButtonWidth), size: buttonSize)
+
+                default:
+                    verticalFrame = CGRect.zero
+                    horizontalFrame = CGRect.zero
+                    buttonFrame = CGRect.zero
+                }
+                
+                corner[0].frame = verticalFrame
+                corner[1].frame = horizontalFrame
+                cornerButtons[i].frame = buttonFrame
+            }
+        }
+		
+		let lineThickness = lineWidth / UIScreen.main.scale
+		let vPadding = (bounds.height - outterGap * 2 - (lineThickness * CGFloat(horizontalLines.count))) / CGFloat(horizontalLines.count + 1)
+		let hPadding = (bounds.width - outterGap * 2 - (lineThickness * CGFloat(verticalLines.count))) / CGFloat(verticalLines.count + 1)
+		
+        for i in 0..<horizontalLines.count {
+            let hLine = horizontalLines[i]
+            let vLine = verticalLines[i]
+			
+			let vSpacing = (vPadding * CGFloat(i + 1)) + (lineThickness * CGFloat(i))
+			let hSpacing = (hPadding * CGFloat(i + 1)) + (lineThickness * CGFloat(i))
+			
+			hLine.frame = CGRect(x: outterGap, y: vSpacing + outterGap, width: bounds.width - outterGap * 2, height:  lineThickness)
+			vLine.frame = CGRect(x: hSpacing + outterGap, y: outterGap, width: lineThickness, height: bounds.height - outterGap * 2)
+        }
+		
+    }
+	
+    func createLines() {
+        
+        outerLines = [createLine(), createLine(), createLine(), createLine()]
+        horizontalLines = [createLine(), createLine()]
+        verticalLines = [createLine(), createLine()]
+        
+        topLeftCornerLines = [createLine(), createLine()]
+        topRightCornerLines = [createLine(), createLine()]
+        bottomLeftCornerLines = [createLine(), createLine()]
+        bottomRightCornerLines = [createLine(), createLine()]
+        
+		cornerButtons = [createButton(), createButton(), createButton(), createButton()]
+		
+		let dragGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(moveCropOverlay))
+		addGestureRecognizer(dragGestureRecognizer)
+    }
+    
+    func createLine() -> UIView {
+        let line = UIView()
+        line.backgroundColor = UIColor.white
+        addSubview(line)
+        return line
+    }
+	
+	func createButton() -> UIButton {
+		let button = UIButton()
+		button.backgroundColor = UIColor.clear
+		
+		let dragGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(moveCropOverlay))
+		button.addGestureRecognizer(dragGestureRecognizer)
+
+		addSubview(button)
+		return button
+	}
+	
+	@objc func moveCropOverlay(gestureRecognizer: UIPanGestureRecognizer) {
+		if isResizable, showsButtons, let button = gestureRecognizer.view as? UIButton {
+			if gestureRecognizer.state == .began || gestureRecognizer.state == .changed {
+				let translation = gestureRecognizer.translation(in: self)
+				
+				var newFrame: CGRect
+				
+				switch button {
+				case cornerButtons[0]:	// Top Left
+                    newFrame = CGRect(x: frame.origin.x + translation.x, y: frame.origin.y + translation.y, width: frame.size.width - translation.x, height: frame.size.height - translation.y)
+				case cornerButtons[1]:	// Top Right
+					newFrame = CGRect(x: frame.origin.x, y: frame.origin.y + translation.y, width: frame.size.width + translation.x, height: frame.size.height - translation.y)
+				case cornerButtons[2]:	// Bottom Left
+					newFrame = CGRect(x: frame.origin.x + translation.x, y: frame.origin.y, width: frame.size.width - translation.x, height: frame.size.height + translation.y)
+				case cornerButtons[3]:	// Bottom Right
+					newFrame = CGRect(x: frame.origin.x, y: frame.origin.y, width: frame.size.width + translation.x, height: frame.size.height + translation.y)
+				default:
+					newFrame = CGRect.zero
+				}
+
+                let minimumFrame = CGRect(x: newFrame.origin.x, y: newFrame.origin.y, width: max(newFrame.size.width, minimumSize.width + 2 * outterGap), height: max(newFrame.size.height, minimumSize.height + 2 * outterGap))
+				frame = minimumFrame
+				layoutSubviews()
+
+				gestureRecognizer.setTranslation(CGPoint.zero, in: self)
+			}
+		} else if isMovable {
+			if gestureRecognizer.state == .began || gestureRecognizer.state == .changed {
+				let translation = gestureRecognizer.translation(in: self)
+				
+				gestureRecognizer.view!.center = CGPoint(x: gestureRecognizer.view!.center.x + translation.x, y: gestureRecognizer.view!.center.y + translation.y)
+				gestureRecognizer.setTranslation(CGPoint(x: 0, y: 0), in: self)
+			}
+		}
+	}
+
+    override func hitTest(_ hitPoint: CGPoint, with event: UIEvent?) -> UIView? {
+        
+        if let view = super.hitTest(hitPoint, with: event) {
+        
+        
+            if isResizable && showsButtons {
+                let isButton = cornerButtons.reduce(false) { $1.hitTest(convert(hitPoint, to: $1), with: event) != nil || $0 }
+                if isButton {  //user hit a resize button, so use our view
+                    return view
+                }
+            }
+            
+            if isMovable {
+                let centerPoint = CGPoint(x: bounds.midX, y: bounds.midY)
+                
+                if centerPoint.distance(to: hitPoint) < centerCircleRadius {
+                    return view  //user is in the center of the view, wants to move it, so use our view
+                }
+            }
+            
+        }
+        return nil
+        
+    }
+    
+
+}
+
+
+extension CGPoint {
+    func distance(to point: CGPoint) -> CGFloat {
+        return sqrt(pow((point.x - x), 2) + pow((point.y - y), 2))
+    }
+}

+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/Views/ImageCell.swift → Pods/KK-ALCameraViewController/ALCameraViewController/Views/ImageCell.swift


+ 0 - 0
Pods/ALCameraViewController/ALCameraViewController/Views/PermissionsView.swift → Pods/KK-ALCameraViewController/ALCameraViewController/Views/PermissionsView.swift


+ 0 - 0
Pods/ALCameraViewController/LICENSE → Pods/KK-ALCameraViewController/LICENSE


+ 58 - 0
Pods/KK-ALCameraViewController/README.md

@@ -0,0 +1,58 @@
+# ALCameraViewController - Forked and Modified
+
+A camera view controller with custom image picker and image cropping. See below for 
+a summary of changes for this fork. For detailed changes see notes in source files.
+
+![cropper](https://cloud.githubusercontent.com/assets/932822/8455697/c627ac44-2006-11e5-82be-7f96e73d9b1f.jpg)
+
+
+## Usage ##
+
+Usage of this fork remains the same as the original but with more options. See the [original README](https://github.com/AlexLittlejohn/ALCameraViewController/blob/master/README.md) for details.
+
+## CocoaPod ##
+
+Incorporate this fork into your project with CocoaPods. Add this line to your podfile:
+
+`pod 'KK-ALCameraViewController'`
+
+## License
+ALCameraViewController is available under the MIT license. See the LICENSE file for more info.  This fork retains the same license.
+
+
+# Changes in this fork
+
+## Compiling
+
+* Updated to Swift 5
+* Updated for compatibility with iOS 13
+
+## Cropping
+
+* Image cropping now uses a rectangle with a specified aspect ratio rather than a square.  
+* Added a center point circle in the middle of the crop rectangle that shows a touch point for moving the crop overlay. Previously, the user could move the crop overlay by dragging anywhere in the crop bounds, but this prevents pinch-resizing of the image except at the very edge. The resize corners still work as before.
+
+## Camera
+
+* Cleaned up the constraints for the flash, swap, and library buttons to work properly in both landscape orientations
+* Update the overlay constraints when rotating, so the overlay is properly positioned and sized
+* If the camera is not available (ie. on simulator), pop up an error rather than crashing
+* Hide flash button if the flash is not available (for instance, iPads)
+
+## Library Picker
+
+* Adding a pinch gesture to increase or decrease the number of columns shown, up to a min or max value
+
+
+## Confirm / Cropping View
+
+* Significant updates to the presentation of the image, scrolling, and cropping to fix inconsistencies especially when switching between portrait and landscape.  See source file for full details.
+* Allow zooming in on the image during cropping
+* Rotate button to rotate the image 90 degrees clockwise on each press
+
+## Example 
+
+* Added a tap gesture on the displayed image to allow re-cropping the image (illustrates bringing up the crop view directly)
+* The example was updated to show a crop aspect ratio of 1.2 
+
+

+ 5 - 5
Pods/Manifest.lock

@@ -1,10 +1,10 @@
 PODS:
-  - ALCameraViewController (3.1)
   - DBDebugToolkit (0.5.0)
   - InputBarAccessoryView (4.3.1):
     - InputBarAccessoryView/Core (= 4.3.1)
   - InputBarAccessoryView/Core (4.3.1)
   - JGProgressHUD (2.0.3)
+  - KK-ALCameraViewController (4.1.0)
   - ReachabilitySwift (4.3.1)
   - SCSiriWaveformView (1.1.1)
   - SwiftFormat/CLI (0.40.9)
@@ -13,10 +13,10 @@ PODS:
   - UICircularProgressRing (6.2.0)
 
 DEPENDENCIES:
-  - ALCameraViewController
   - DBDebugToolkit
   - InputBarAccessoryView
   - JGProgressHUD
+  - KK-ALCameraViewController
   - ReachabilitySwift
   - SCSiriWaveformView
   - SwiftFormat/CLI
@@ -26,10 +26,10 @@ DEPENDENCIES:
 
 SPEC REPOS:
   trunk:
-    - ALCameraViewController
     - DBDebugToolkit
     - InputBarAccessoryView
     - JGProgressHUD
+    - KK-ALCameraViewController
     - ReachabilitySwift
     - SCSiriWaveformView
     - SwiftFormat
@@ -38,10 +38,10 @@ SPEC REPOS:
     - UICircularProgressRing
 
 SPEC CHECKSUMS:
-  ALCameraViewController: 144dea45fd749a623aafd8cb7b10cea88499fcc3
   DBDebugToolkit: c04bb6f618051d3de447a4b4323f37826116cfed
   InputBarAccessoryView: 58a348be7ea2736c7eec60e5c315511c2dbb39fd
   JGProgressHUD: 12b20a8f4ffe05258f8635c1ab92816e451f904d
+  KK-ALCameraViewController: ea8d8b24c9a7b92f61508a5a41ef8332f4ef7903
   ReachabilitySwift: 4032e2f59586e11e3b0ebe15b167abdd587a388b
   SCSiriWaveformView: 15b9dd6f94c7536e2032b34a35c6ff74d38c7411
   SwiftFormat: 6b67b6e7fe73d664f0cbb4f13721f130462c86a5
@@ -49,6 +49,6 @@ SPEC CHECKSUMS:
   SwiftyBeaver: 4cc0080d2e23f980652e28978db11a5c9da39165
   UICircularProgressRing: 0ff679b05a17f15ad6301a7886686837b8c301a9
 
-PODFILE CHECKSUM: 055466769932ef70c4999b1faacbdf7883a8e6d8
+PODFILE CHECKSUM: a98070d2fb3a559fc76c7d76ff4cf4ea68108ac1
 
 COCOAPODS: 1.8.4

File diff suppressed because it is too large
+ 797 - 797
Pods/Pods.xcodeproj/project.pbxproj


+ 0 - 5
Pods/Target Support Files/ALCameraViewController/ALCameraViewController-dummy.m

@@ -1,5 +0,0 @@
-#import <Foundation/Foundation.h>
-@interface PodsDummy_ALCameraViewController : NSObject
-@end
-@implementation PodsDummy_ALCameraViewController
-@end

+ 0 - 6
Pods/Target Support Files/ALCameraViewController/ALCameraViewController.modulemap

@@ -1,6 +0,0 @@
-framework module ALCameraViewController {
-  umbrella header "ALCameraViewController-umbrella.h"
-
-  export *
-  module * { export * }
-}

+ 1 - 1
Pods/Target Support Files/ALCameraViewController/ALCameraViewController-Info.plist → Pods/Target Support Files/KK-ALCameraViewController/KK-ALCameraViewController-Info.plist

@@ -15,7 +15,7 @@
   <key>CFBundlePackageType</key>
   <string>FMWK</string>
   <key>CFBundleShortVersionString</key>
-  <string>3.1.0</string>
+  <string>4.1.0</string>
   <key>CFBundleSignature</key>
   <string>????</string>
   <key>CFBundleVersion</key>

+ 5 - 0
Pods/Target Support Files/KK-ALCameraViewController/KK-ALCameraViewController-dummy.m

@@ -0,0 +1,5 @@
+#import <Foundation/Foundation.h>
+@interface PodsDummy_KK_ALCameraViewController : NSObject
+@end
+@implementation PodsDummy_KK_ALCameraViewController
+@end

+ 0 - 0
Pods/Target Support Files/ALCameraViewController/ALCameraViewController-prefix.pch → Pods/Target Support Files/KK-ALCameraViewController/KK-ALCameraViewController-prefix.pch


+ 2 - 2
Pods/Target Support Files/ALCameraViewController/ALCameraViewController-umbrella.h → Pods/Target Support Files/KK-ALCameraViewController/KK-ALCameraViewController-umbrella.h

@@ -11,6 +11,6 @@
 #endif
 
 
-FOUNDATION_EXPORT double ALCameraViewControllerVersionNumber;
-FOUNDATION_EXPORT const unsigned char ALCameraViewControllerVersionString[];
+FOUNDATION_EXPORT double KK_ALCameraViewControllerVersionNumber;
+FOUNDATION_EXPORT const unsigned char KK_ALCameraViewControllerVersionString[];
 

+ 6 - 0
Pods/Target Support Files/KK-ALCameraViewController/KK-ALCameraViewController.modulemap

@@ -0,0 +1,6 @@
+framework module KK_ALCameraViewController {
+  umbrella header "KK-ALCameraViewController-umbrella.h"
+
+  export *
+  module * { export * }
+}

Some files were not shown because too many files changed in this diff