Skip to content
This repository has been archived by the owner on Apr 6, 2020. It is now read-only.

Added ability to lock the height/width ration when cropping #9

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 22 additions & 12 deletions Classes/WDCropBorderView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,22 @@ import UIKit
internal class WDCropBorderView: UIView {
private let kNumberOfBorderHandles: CGFloat = 8
private let kHandleDiameter: CGFloat = 24
private var lockAspectRatio: Bool

convenience init(frame: CGRect, lockAspectRatio locked: Bool) {
self.init(frame: frame)
self.lockAspectRatio = locked
}

override init(frame: CGRect) {
self.lockAspectRatio = false
super.init(frame: frame)

self.backgroundColor = UIColor.clearColor()
}

required init?(coder aDecoder: NSCoder) {
self.lockAspectRatio = false
super.init(coder: aDecoder)

self.backgroundColor = UIColor.clearColor()
Expand Down Expand Up @@ -53,17 +61,19 @@ internal class WDCropBorderView: UIView {
let bottomRowY = height - kHandleDiameter
let middleRowY = bottomRowY / 2

//starting with the upper left corner and then following clockwise
let topLeft = CGRectMake(leftColX, topRowY, kHandleDiameter, kHandleDiameter)
let topCenter = CGRectMake(centerColX, topRowY, kHandleDiameter, kHandleDiameter)
let topRight = CGRectMake(rightColX, topRowY, kHandleDiameter, kHandleDiameter)
let middleRight = CGRectMake(rightColX, middleRowY, kHandleDiameter, kHandleDiameter)
let bottomRight = CGRectMake(rightColX, bottomRowY, kHandleDiameter, kHandleDiameter)
let bottomCenter = CGRectMake(centerColX, bottomRowY, kHandleDiameter, kHandleDiameter)
let bottomLeft = CGRectMake(leftColX, bottomRowY, kHandleDiameter, kHandleDiameter)
let middleLeft = CGRectMake(leftColX, middleRowY, kHandleDiameter, kHandleDiameter)

return [topLeft, topCenter, topRight, middleRight, bottomRight, bottomCenter, bottomLeft,
middleLeft]
var handleArray = [CGRect]()
handleArray.append(CGRectMake(leftColX, topRowY, kHandleDiameter, kHandleDiameter)) //top left
handleArray.append(CGRectMake(rightColX, topRowY, kHandleDiameter, kHandleDiameter)) //top right
handleArray.append(CGRectMake(rightColX, bottomRowY, kHandleDiameter, kHandleDiameter)) //bottom right
handleArray.append(CGRectMake(leftColX, bottomRowY, kHandleDiameter, kHandleDiameter)) //bottom left

if !lockAspectRatio {
handleArray.append(CGRectMake(centerColX, topRowY, kHandleDiameter, kHandleDiameter)) //top center
handleArray.append(CGRectMake(rightColX, middleRowY, kHandleDiameter, kHandleDiameter)) //middle right
handleArray.append(CGRectMake(centerColX, bottomRowY, kHandleDiameter, kHandleDiameter)) //bottom center
handleArray.append(CGRectMake(leftColX, middleRowY, kHandleDiameter, kHandleDiameter)) //middle left
}

return handleArray
}
Copy link
Author

@perfaram perfaram Aug 2, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When aspect ratio is locked, show only the handles located at the angles.

}
3 changes: 2 additions & 1 deletion Classes/WDImageCropView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ private class ScrollView: UIScrollView {

internal class WDImageCropView: UIView, UIScrollViewDelegate {
var resizableCropArea = false
var lockAspectRatio = false

private var scrollView: UIScrollView!
private var imageView: UIImageView!
Expand Down Expand Up @@ -72,7 +73,7 @@ internal class WDImageCropView: UIView, UIScrollViewDelegate {
} else {
if self.resizableCropArea {
self.cropOverlayView = WDResizableCropOverlayView(frame: self.bounds,
initialContentSize: CGSizeMake(newValue.width, newValue.height))
initialContentSize: CGSizeMake(newValue.width, newValue.height), lockAspectRatio: self.lockAspectRatio)
} else {
self.cropOverlayView = WDImageCropOverlayView(frame: self.bounds)
}
Expand Down
2 changes: 2 additions & 0 deletions Classes/WDImageCropViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ internal class WDImageCropViewController: UIViewController {
var delegate: WDImageCropControllerDelegate?
var cropSize: CGSize!
var resizableCropArea = false
var lockAspectRatio = false

private var croppedImage: UIImage!

Expand Down Expand Up @@ -72,6 +73,7 @@ internal class WDImageCropViewController: UIViewController {
self.imageCropView = WDImageCropView(frame: self.view.bounds)
self.imageCropView.imageToCrop = sourceImage
self.imageCropView.resizableCropArea = self.resizableCropArea
self.imageCropView.lockAspectRatio = self.lockAspectRatio
self.imageCropView.cropSize = cropSize
self.view.addSubview(self.imageCropView)
}
Expand Down
2 changes: 2 additions & 0 deletions Classes/WDImagePicker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import UIKit
public var delegate: WDImagePickerDelegate?
public var cropSize: CGSize!
public var resizableCropArea = false
public var lockAspectRatio = false

private var _imagePickerController: UIImagePickerController!

Expand Down Expand Up @@ -49,6 +50,7 @@ import UIKit
let cropController = WDImageCropViewController()
cropController.sourceImage = info[UIImagePickerControllerOriginalImage] as! UIImage
cropController.resizableCropArea = self.resizableCropArea
cropController.lockAspectRatio = self.lockAspectRatio
cropController.cropSize = self.cropSize
cropController.delegate = self
picker.pushViewController(cropController, animated: true)
Expand Down
83 changes: 63 additions & 20 deletions Classes/WDResizableCropOverlayView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ internal class WDResizableCropOverlayView: WDImageCropOverlayView {
private var anchor: CGPoint!
private var startPoint: CGPoint!
private var resizeMultiplyer = WDResizableViewBorderMultiplyer()
private var lockAspectRatio: Bool = false

override var frame: CGRect {
get {
Expand All @@ -52,9 +53,9 @@ internal class WDResizableCropOverlayView: WDImageCropOverlayView {
}
}

init(frame: CGRect, initialContentSize: CGSize) {
init(frame: CGRect, initialContentSize: CGSize, lockAspectRatio locked: Bool = false) {
super.init(frame: frame)

self.lockAspectRatio = locked
self.initialContentSize = initialContentSize
self.addContentViews()
}
Expand Down Expand Up @@ -114,7 +115,7 @@ internal class WDResizableCropOverlayView: WDImageCropOverlayView {
(width - initialContentSize.width) / 2 - kBorderCorrectionValue,
(height - toolbarSize - initialContentSize.height) / 2 - kBorderCorrectionValue,
initialContentSize.width + kBorderCorrectionValue * 2,
initialContentSize.height + kBorderCorrectionValue * 2))
initialContentSize.height + kBorderCorrectionValue * 2), lockAspectRatio: self.lockAspectRatio)
self.addSubview(cropBorderView)
}

Expand Down Expand Up @@ -145,23 +146,26 @@ internal class WDResizableCropOverlayView: WDImageCropOverlayView {
let bottomY = cropBorderView.bounds.size.height
let middleY = topY + (bottomY - topY) / 2

// starting with the upper left corner and then following the rect clockwise
let topLeft = CGPointMake(leftX, topY)
let topCenter = CGPointMake(centerX, topY)
let topRight = CGPointMake(rightX, topY)
let middleRight = CGPointMake(rightX, middleY)
let bottomRight = CGPointMake(rightX, bottomY)
let bottomCenter = CGPointMake(centerX, bottomY)
let bottomLeft = CGPointMake(leftX, bottomY)
let middleLeft = CGPointMake(leftX, middleY)

return [topLeft, topCenter, topRight, middleRight, bottomRight, bottomCenter, bottomLeft,
middleLeft]
var handleArray = [CGPoint]()
handleArray.append(CGPointMake(leftX, topY)) //top left
handleArray.append(CGPointMake(rightX, topY)) //top right
handleArray.append(CGPointMake(rightX, bottomY)) //bottom right
handleArray.append(CGPointMake(leftX, bottomY)) //bottom left

if !lockAspectRatio {
handleArray.append(CGPointMake(centerX, topY)) //top center
handleArray.append(CGPointMake(rightX, middleY)) //middle right
handleArray.append(CGPointMake(centerX, bottomY)) //bottom center
handleArray.append(CGPointMake(leftX, middleY)) //middle left
}

return handleArray
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When aspect ratio is locked, show only the handles located at the angles.

}

private func resizeWithTouchPoint(point: CGPoint) {
// This is the place where all the magic happends
// prevent goint offscreen...

let border = kBorderCorrectionValue * 2
var pointX = point.x < border ? border : point.x
var pointY = point.y < border ? border : point.y
Expand All @@ -170,11 +174,19 @@ internal class WDResizableCropOverlayView: WDImageCropOverlayView {
pointY = pointY > self.superview!.bounds.size.height - border ?
self.superview!.bounds.size.height - border : pointY

let heightChange = (pointY - startPoint.y) * resizeMultiplyer.heightMultiplyer
let widthChange = (startPoint.x - pointX) * resizeMultiplyer.widthMultiplyer
var heightChange = (pointY - startPoint.y) * resizeMultiplyer.heightMultiplyer
var widthChange = (startPoint.x - pointX) * resizeMultiplyer.widthMultiplyer

if lockAspectRatio {
let averageChange = (heightChange + widthChange) / 2
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ensures that the handle currently used for resizing doesn't get too far from the user's touch point.

heightChange = averageChange
widthChange = averageChange
}

let xChange = -1 * widthChange * resizeMultiplyer.xMultiplyer
let yChange = -1 * heightChange * resizeMultiplyer.yMultiplyer


var newFrame = CGRectMake(
cropBorderView.frame.origin.x + xChange,
cropBorderView.frame.origin.y + yChange,
Expand All @@ -192,31 +204,62 @@ internal class WDResizableCropOverlayView: WDImageCropOverlayView {
if newFrame.size.width < 64 {
newFrame.size.width = cropBorderView.frame.size.width
newFrame.origin.x = cropBorderView.frame.origin.x
if lockAspectRatio {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Equilibrates changes between width & height to keep ratio (just like all other changes made in this function).

newFrame.size.height = cropBorderView.frame.size.height
newFrame.origin.y = cropBorderView.frame.origin.y
}
}

if newFrame.size.height < 64 {
newFrame.size.height = cropBorderView.frame.size.height
newFrame.origin.y = cropBorderView.frame.origin.y
if lockAspectRatio {
newFrame.size.width = cropBorderView.frame.size.width
newFrame.origin.x = cropBorderView.frame.origin.x
}
}

if newFrame.origin.x < 0 {
newFrame.size.width = cropBorderView.frame.size.width +
(cropBorderView.frame.origin.x - self.superview!.bounds.origin.x)
newFrame.origin.x = 0
if lockAspectRatio {
newFrame.size.height = cropBorderView.frame.size.height +
(cropBorderView.frame.origin.y - self.superview!.bounds.origin.y)
newFrame.origin.y = 0
}
}

if newFrame.origin.y < 0 {
newFrame.size.height = cropBorderView.frame.size.height +
(cropBorderView.frame.origin.y - self.superview!.bounds.origin.y)
newFrame.origin.y = 0
if lockAspectRatio {
newFrame.size.width = cropBorderView.frame.size.width +
(cropBorderView.frame.origin.x - self.superview!.bounds.origin.x)
newFrame.origin.x = 0
}
}

if newFrame.size.width + newFrame.origin.x > self.frame.size.width {
newFrame.size.width = self.frame.size.width - cropBorderView.frame.origin.x
if lockAspectRatio {
newFrame.size.width = cropBorderView.frame.size.width
newFrame.size.height = cropBorderView.frame.size.height
}
else {
newFrame.size.width = self.frame.size.width - cropBorderView.frame.origin.x
}
}

if newFrame.size.height + newFrame.origin.y > self.frame.size.height - toolbarSize {
newFrame.size.height = self.frame.size.height -
cropBorderView.frame.origin.y - toolbarSize
if lockAspectRatio {
newFrame.size.width = cropBorderView.frame.size.width
newFrame.size.height = cropBorderView.frame.size.height
}
else {
newFrame.size.height = self.frame.size.height -
cropBorderView.frame.origin.y - toolbarSize
}
}

return newFrame
Expand Down