Skip to content
This repository was archived by the owner on Jul 1, 2022. It is now read-only.

Commit d88b584

Browse files
Merge branch 'Tulleb-feature/resize-cropping-area' into develop
2 parents 7936632 + 4a80d04 commit d88b584

File tree

9 files changed

+347
-127
lines changed

9 files changed

+347
-127
lines changed

ALCameraViewController.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
7AC96FA21F5B5166003E53F4 /* CroppingParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AC96FA11F5B5166003E53F4 /* CroppingParameters.swift */; };
1011
C40665441C73A47C00EB9751 /* SingleImageSaver.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40665431C73A47C00EB9751 /* SingleImageSaver.swift */; };
1112
C40665461C73A94100EB9751 /* CameraGlobals.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40665451C73A94100EB9751 /* CameraGlobals.swift */; };
1213
C40665481C73B72D00EB9751 /* SingleImageFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40665471C73B72D00EB9751 /* SingleImageFetcher.swift */; };
@@ -58,6 +59,7 @@
5859
/* End PBXBuildFile section */
5960

6061
/* Begin PBXFileReference section */
62+
7AC96FA11F5B5166003E53F4 /* CroppingParameters.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CroppingParameters.swift; sourceTree = "<group>"; };
6163
C40665431C73A47C00EB9751 /* SingleImageSaver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleImageSaver.swift; sourceTree = "<group>"; };
6264
C40665451C73A94100EB9751 /* CameraGlobals.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CameraGlobals.swift; sourceTree = "<group>"; };
6365
C40665471C73B72D00EB9751 /* SingleImageFetcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleImageFetcher.swift; sourceTree = "<group>"; };
@@ -154,6 +156,7 @@
154156
C4D9BA441CA7224B004F70F7 /* PhotoLibraryAuthorizer.swift */,
155157
C4D9BA461CA73163004F70F7 /* UIButtonExtensions.swift */,
156158
EBFE097C1CAF1D1A00A8C637 /* UIViewExtensions.swift */,
159+
7AC96FA11F5B5166003E53F4 /* CroppingParameters.swift */,
157160
);
158161
path = Utilities;
159162
sourceTree = "<group>";
@@ -366,6 +369,7 @@
366369
FAB50C001B413E8C009905B9 /* PhotoLibraryViewController.swift in Sources */,
367370
FAF0586A1B317894008E5592 /* CameraShot.swift in Sources */,
368371
FAF058661B316695008E5592 /* CameraViewController.swift in Sources */,
372+
7AC96FA21F5B5166003E53F4 /* CroppingParameters.swift in Sources */,
369373
C4D9BA451CA7224B004F70F7 /* PhotoLibraryAuthorizer.swift in Sources */,
370374
FAB50BFB1B413E8C009905B9 /* ImageCell.swift in Sources */,
371375
EBFE097D1CAF1D1A00A8C637 /* UIViewExtensions.swift in Sources */,
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//
2+
// CroppingParameters.swift
3+
// ALCameraViewController
4+
//
5+
// Created by Guillaume Bellut on 02/09/2017.
6+
// Copyright © 2017 zero. All rights reserved.
7+
//
8+
9+
import UIKit
10+
11+
public struct CroppingParameters {
12+
13+
/// Enable the cropping feature.
14+
/// Default value is set to false.
15+
var isEnabled: Bool
16+
17+
/// Allow the cropping area to be resized by the user.
18+
/// Default value is set to true.
19+
var allowResizing: Bool
20+
21+
/// Prevent the user to resize the cropping area below a minimum size.
22+
/// Default value is (60, 60). Below this value, corner buttons will overlap.
23+
var minimumSize: CGSize
24+
25+
init(isEnabled: Bool = false,
26+
allowResizing: Bool = true,
27+
minimumSize: CGSize = CGSize(width: 60, height: 60)) {
28+
29+
self.isEnabled = isEnabled
30+
self.allowResizing = allowResizing
31+
self.minimumSize = minimumSize
32+
}
33+
}

ALCameraViewController/Utilities/SingleImageFetcher.swift

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,11 @@ public class SingleImageFetcher {
7878
options.resizeMode = .exact
7979

8080
let targetWidth = floor(CGFloat(asset.pixelWidth) * cropRect.width)
81-
let targetHeight = floor(CGFloat(asset.pixelHeight) * cropRect.height)
82-
let dimension = max(min(targetHeight, targetWidth), 1024 * scale)
83-
84-
targetSize = CGSize(width: dimension, height: dimension)
81+
let targetHeight = floor(CGFloat(asset.pixelHeight) * cropRect.height)
82+
83+
targetSize = CGSize(width: targetWidth, height: targetHeight)
8584
}
86-
85+
8786
PHImageManager.default().requestImage(for: asset, targetSize: targetSize, contentMode: .aspectFill, options: options) { image, _ in
8887
if let image = image {
8988
self.success?(image)

ALCameraViewController/ViewController/CameraViewController.swift

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public typealias CameraViewCompletion = (UIImage?, PHAsset?) -> Void
1414

1515
public extension CameraViewController {
1616
/// Provides an image picker wrapped inside a UINavigationController instance
17-
public class func imagePickerViewController(croppingEnabled: Bool, completion: @escaping CameraViewCompletion) -> UINavigationController {
17+
public class func imagePickerViewController(croppingParameters: CroppingParameters, completion: @escaping CameraViewCompletion) -> UINavigationController {
1818
let imagePicker = PhotoLibraryViewController()
1919
let navigationController = UINavigationController(rootViewController: imagePicker)
2020

@@ -24,7 +24,7 @@ public extension CameraViewController {
2424

2525
imagePicker.onSelectionComplete = { [weak imagePicker] asset in
2626
if let asset = asset {
27-
let confirmController = ConfirmViewController(asset: asset, allowsCropping: croppingEnabled)
27+
let confirmController = ConfirmViewController(asset: asset, croppingParameters: croppingParameters)
2828
confirmController.onComplete = { [weak imagePicker] image, asset in
2929
if let image = image, let asset = asset {
3030
completion(image, asset)
@@ -46,7 +46,7 @@ public extension CameraViewController {
4646
open class CameraViewController: UIViewController {
4747

4848
var didUpdateViews = false
49-
var allowCropping = false
49+
var croppingParameters: CroppingParameters
5050
var animationRunning = false
5151
let allowVolumeButtonCapture: Bool
5252

@@ -89,7 +89,7 @@ open class CameraViewController: UIViewController {
8989
cameraView.translatesAutoresizingMaskIntoConstraints = false
9090
return cameraView
9191
}()
92-
92+
9393
let cameraOverlay : CropOverlay = {
9494
let cameraOverlay = CropOverlay()
9595
cameraOverlay.translatesAutoresizingMaskIntoConstraints = false
@@ -159,13 +159,18 @@ open class CameraViewController: UIViewController {
159159

160160
private let allowsLibraryAccess: Bool
161161

162-
public init(croppingEnabled: Bool, allowsLibraryAccess: Bool = true, allowsSwapCameraOrientation: Bool = true, allowVolumeButtonCapture: Bool = true, completion: @escaping CameraViewCompletion) {
163-
self.allowsLibraryAccess = allowsLibraryAccess
162+
public init(croppingParameters: CroppingParameters = CroppingParameters(),
163+
allowsLibraryAccess: Bool = true,
164+
allowsSwapCameraOrientation: Bool = true,
165+
allowVolumeButtonCapture: Bool = true,
166+
completion: @escaping CameraViewCompletion) {
167+
168+
self.croppingParameters = croppingParameters
169+
self.allowsLibraryAccess = allowsLibraryAccess
164170
self.allowVolumeButtonCapture = allowVolumeButtonCapture
165171
super.init(nibName: nil, bundle: nil)
166172
onCompletion = completion
167-
allowCropping = croppingEnabled
168-
cameraOverlay.isHidden = !allowCropping
173+
cameraOverlay.isHidden = !croppingParameters.isEnabled
169174
libraryButton.isEnabled = allowsLibraryAccess
170175
libraryButton.isHidden = !allowsLibraryAccess
171176
swapButton.isEnabled = allowsSwapCameraOrientation
@@ -539,7 +544,7 @@ open class CameraViewController: UIViewController {
539544
}
540545

541546
internal func showLibrary() {
542-
let imagePicker = CameraViewController.imagePickerViewController(croppingEnabled: allowCropping) { [weak self] image, asset in
547+
let imagePicker = CameraViewController.imagePickerViewController(croppingParameters: croppingParameters) { [weak self] image, asset in
543548
defer {
544549
self?.dismiss(animated: true, completion: nil)
545550
}
@@ -588,7 +593,7 @@ open class CameraViewController: UIViewController {
588593
}
589594

590595
private func startConfirmController(uiImage: UIImage) {
591-
let confirmViewController = ConfirmViewController(image: uiImage, allowsCropping: allowCropping)
596+
let confirmViewController = ConfirmViewController(image: uiImage, croppingParameters: croppingParameters)
592597
confirmViewController.onComplete = { [weak self] image, asset in
593598
defer {
594599
self?.dismiss(animated: true, completion: nil)
@@ -606,7 +611,7 @@ open class CameraViewController: UIViewController {
606611
}
607612

608613
private func startConfirmController(asset: PHAsset) {
609-
let confirmViewController = ConfirmViewController(asset: asset, allowsCropping: allowCropping)
614+
let confirmViewController = ConfirmViewController(asset: asset, croppingParameters: croppingParameters)
610615
confirmViewController.onComplete = { [weak self] image, asset in
611616
defer {
612617
self?.dismiss(animated: true, completion: nil)

ALCameraViewController/ViewController/ConfirmViewController.swift

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,33 +18,37 @@ public class ConfirmViewController: UIViewController, UIScrollViewDelegate {
1818
@IBOutlet weak var confirmButton: UIButton!
1919
@IBOutlet weak var centeringView: UIView!
2020

21-
var allowsCropping: Bool = false
21+
var croppingParameters: CroppingParameters {
22+
didSet {
23+
cropOverlay.isResizable = croppingParameters.allowResizing
24+
cropOverlay.minimumSize = croppingParameters.minimumSize
25+
}
26+
}
27+
2228
var verticalPadding: CGFloat = 30
2329
var horizontalPadding: CGFloat = 30
2430

2531
public var onComplete: CameraViewCompletion?
26-
32+
2733
let asset: PHAsset?
2834
let image: UIImage?
2935

30-
public init(image: UIImage, allowsCropping: Bool) {
31-
self.allowsCropping = allowsCropping
36+
public init(image: UIImage, croppingParameters: CroppingParameters) {
37+
self.croppingParameters = croppingParameters
3238
self.asset = nil
3339
self.image = image
3440
super.init(nibName: "ConfirmViewController", bundle: CameraGlobals.shared.bundle)
3541
}
3642

37-
public init(asset: PHAsset, allowsCropping: Bool) {
38-
self.allowsCropping = allowsCropping
43+
public init(asset: PHAsset, croppingParameters: CroppingParameters) {
44+
self.croppingParameters = croppingParameters
3945
self.asset = asset
4046
self.image = nil
4147
super.init(nibName: "ConfirmViewController", bundle: CameraGlobals.shared.bundle)
4248
}
4349

44-
public required init?(coder aDecoder: NSCoder) {
45-
asset = nil
46-
image = nil
47-
super.init(coder: aDecoder)
50+
public required init?(coder aDecoder: NSCoder) {
51+
fatalError("init(coder:) has not been implemented")
4852
}
4953

5054
public override var prefersStatusBarHidden: Bool {
@@ -57,15 +61,17 @@ public class ConfirmViewController: UIViewController, UIScrollViewDelegate {
5761

5862
public override func viewDidLoad() {
5963
super.viewDidLoad()
60-
64+
6165
view.backgroundColor = UIColor.black
6266

6367
scrollView.addSubview(imageView)
6468
scrollView.delegate = self
6569
scrollView.maximumZoomScale = 1
6670

67-
cropOverlay.isHidden = true
68-
71+
cropOverlay.isHidden = true
72+
cropOverlay.isResizable = croppingParameters.allowResizing
73+
cropOverlay.minimumSize = croppingParameters.minimumSize
74+
6975
let spinner = showSpinner()
7076

7177
disable()
@@ -93,7 +99,7 @@ public class ConfirmViewController: UIViewController, UIScrollViewDelegate {
9399
public override func viewWillLayoutSubviews() {
94100
super.viewWillLayoutSubviews()
95101
let scale = calculateMinimumScale(view.frame.size)
96-
let frame = allowsCropping ? cropOverlay.frame : view.bounds
102+
let frame = croppingParameters.isEnabled ? cropOverlay.frame : view.bounds
97103

98104
scrollView.contentInset = calculateScrollViewInsets(frame)
99105
scrollView.minimumZoomScale = scale
@@ -108,7 +114,7 @@ public class ConfirmViewController: UIViewController, UIScrollViewDelegate {
108114
let scale = calculateMinimumScale(size)
109115
var frame = view.bounds
110116

111-
if allowsCropping {
117+
if croppingParameters.isEnabled {
112118
frame = cropOverlay.frame
113119
let centeringFrame = centeringView.frame
114120
var origin: CGPoint
@@ -139,11 +145,7 @@ public class ConfirmViewController: UIViewController, UIScrollViewDelegate {
139145
}
140146

141147
private func configureWithImage(_ image: UIImage) {
142-
if allowsCropping {
143-
cropOverlay.isHidden = false
144-
} else {
145-
cropOverlay.isHidden = true
146-
}
148+
cropOverlay.isHidden = !croppingParameters.isEnabled
147149

148150
buttonActions()
149151

@@ -155,7 +157,7 @@ public class ConfirmViewController: UIViewController, UIScrollViewDelegate {
155157
private func calculateMinimumScale(_ size: CGSize) -> CGFloat {
156158
var _size = size
157159

158-
if allowsCropping {
160+
if croppingParameters.isEnabled {
159161
_size = cropOverlay.frame.size
160162
}
161163

@@ -168,7 +170,7 @@ public class ConfirmViewController: UIViewController, UIScrollViewDelegate {
168170

169171
var scale: CGFloat
170172

171-
if allowsCropping {
173+
if croppingParameters.isEnabled {
172174
scale = max(scaleWidth, scaleHeight)
173175
} else {
174176
scale = min(scaleWidth, scaleHeight)
@@ -185,8 +187,8 @@ public class ConfirmViewController: UIViewController, UIScrollViewDelegate {
185187
}
186188

187189
private func centerImageViewOnRotate() {
188-
if allowsCropping {
189-
let size = allowsCropping ? cropOverlay.frame.size : scrollView.frame.size
190+
if croppingParameters.isEnabled {
191+
let size = cropOverlay.frame.size
190192
let scrollInsets = scrollView.contentInset
191193
let imageSize = imageView.frame.size
192194
var contentOffset = CGPoint(x: -scrollInsets.left, y: -scrollInsets.top)
@@ -197,7 +199,7 @@ public class ConfirmViewController: UIViewController, UIScrollViewDelegate {
197199
}
198200

199201
private func centerScrollViewContents() {
200-
let size = allowsCropping ? cropOverlay.frame.size : scrollView.frame.size
202+
let size = croppingParameters.isEnabled ? cropOverlay.frame.size : scrollView.frame.size
201203
let imageSize = imageView.frame.size
202204
var imageOrigin = CGPoint.zero
203205

@@ -245,7 +247,7 @@ public class ConfirmViewController: UIViewController, UIScrollViewDelegate {
245247
self?.showNoImageScreen(error)
246248
}
247249
.setAsset(asset)
248-
if allowsCropping {
250+
if croppingParameters.isEnabled {
249251
let rect = normalizedRect(makeProportionalCropRect(), orientation: image.imageOrientation)
250252
fetcher = fetcher.setCropRect(rect)
251253
}
@@ -254,7 +256,7 @@ public class ConfirmViewController: UIViewController, UIScrollViewDelegate {
254256
} else {
255257
var newImage = image
256258

257-
if allowsCropping {
259+
if croppingParameters.isEnabled {
258260
let cropRect = makeProportionalCropRect()
259261
let resizedCropRect = CGRect(x: (image.size.width) * cropRect.origin.x,
260262
y: (image.size.height) * cropRect.origin.y,
@@ -311,7 +313,10 @@ public class ConfirmViewController: UIViewController, UIScrollViewDelegate {
311313
}
312314

313315
private func makeProportionalCropRect() -> CGRect {
314-
var cropRect = cropOverlay.frame
316+
var cropRect = CGRect(x: cropOverlay.frame.origin.x + cropOverlay.outterGap,
317+
y: cropOverlay.frame.origin.y + cropOverlay.outterGap,
318+
width: cropOverlay.frame.size.width - 2 * cropOverlay.outterGap,
319+
height: cropOverlay.frame.size.height - 2 * cropOverlay.outterGap)
315320
cropRect.origin.x += scrollView.contentOffset.x
316321
cropRect.origin.y += scrollView.contentOffset.y
317322

0 commit comments

Comments
 (0)