Skip to content

Commit

Permalink
feat: add CropToolbarIconProvider protocol (#169)
Browse files Browse the repository at this point in the history
use SF symbols for icons inside.
  • Loading branch information
guoyingtao committed Jul 3, 2022
1 parent a73b728 commit 42b89cd
Show file tree
Hide file tree
Showing 10 changed files with 50 additions and 195 deletions.
7 changes: 3 additions & 4 deletions Example/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina4_7" orientation="portrait" appearance="dark"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
Expand Down Expand Up @@ -171,7 +171,6 @@
</imageView>
</subviews>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="vyB-So-c13" firstAttribute="top" secondItem="pUS-Eo-0ui" secondAttribute="bottom" constant="16" id="3Ig-aR-0l7"/>
<constraint firstItem="6Tk-OE-BBY" firstAttribute="bottom" secondItem="vyB-So-c13" secondAttribute="bottom" constant="32" id="EFp-sl-UGU"/>
Expand Down
2 changes: 2 additions & 0 deletions Example/CustomizedCropToolbar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import UIKit
import Mantis

class CustomizedCropToolbar: UIView, CropToolbarProtocol {
var iconProvider: CropToolbarIconProvider?

var heightForVerticalOrientationConstraint: NSLayoutConstraint?
var widthForHorizonOrientationConstraint: NSLayoutConstraint?
weak var cropToolbarDelegate: CropToolbarDelegate?
Expand Down
2 changes: 2 additions & 0 deletions Example/CustomizedCropToolbarWithoutList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import UIKit
import Mantis

class CustomizedCropToolbarWithoutList: UIView, CropToolbarProtocol {
var iconProvider: CropToolbarIconProvider?

var heightForVerticalOrientationConstraint: NSLayoutConstraint?
var widthForHorizonOrientationConstraint: NSLayoutConstraint?
weak var cropToolbarDelegate: CropToolbarDelegate?
Expand Down
4 changes: 2 additions & 2 deletions Example/MantisExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@
DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER = YES;
DEVELOPMENT_TEAM = 3V26Q55U3S;
INFOPLIST_FILE = "$(SRCROOT)/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand All @@ -514,7 +514,7 @@
DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER = YES;
DEVELOPMENT_TEAM = 3V26Q55U3S;
INFOPLIST_FILE = "$(SRCROOT)/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down
3 changes: 0 additions & 3 deletions Example/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ class ViewController: UIViewController, CropViewControllerDelegate {
super.viewDidLoad()

self.imagePicker = ImagePicker(presentationController: self, delegate: self)

// let cropInfo = CropInfo(translation: CGPoint(x: 94.13632915167773, y: 249.0606067401352), rotation: 0.7700574398040771, scale: 3.7635509462072614, cropSize: CGSize(width: 230.31290201917224, height: 728.0), imageViewSize: CGSize(width: 400.0, height: 600.0))
// croppedImageView.image = Mantis.crop(image: image!, by: cropInfo)
}

override var preferredStatusBarStyle: UIStatusBarStyle {
Expand Down
4 changes: 2 additions & 2 deletions Mantis.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -819,7 +819,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MACOSX_DEPLOYMENT_TARGET = 10.15;
ONLY_ACTIVE_ARCH = YES;
OTHER_SWIFT_FLAGS = "$(inherited) -DXcode";
Expand Down Expand Up @@ -873,7 +873,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MACOSX_DEPLOYMENT_TARGET = 10.15;
OTHER_SWIFT_FLAGS = "$(inherited) -DXcode";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
</p>

## Requirements
* iOS 11.0+
* iOS 13.0+
* MacOS 10.15+
* Xcode 10.0+

Expand Down
18 changes: 12 additions & 6 deletions Sources/Mantis/CropViewController/CropToolbar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public enum CropToolbarMode {
}

public class CropToolbar: UIView, CropToolbarProtocol {
public var iconProvider: CropToolbarIconProvider?

public var heightForVerticalOrientationConstraint: NSLayoutConstraint?
public var widthForHorizonOrientationConstraint: NSLayoutConstraint?

Expand Down Expand Up @@ -57,23 +59,25 @@ public class CropToolbar: UIView, CropToolbarProtocol {

private func createCancelButton() {
let cancelText = LocalizedHelper.getString("Mantis.Cancel", value: "Cancel")

cancelButton = createOptionButton(withTitle: cancelText, andAction: #selector(cancel))
}

private func createCounterClockwiseRotationButton() {
counterClockwiseRotationButton = createOptionButton(withTitle: nil, andAction: #selector(counterClockwiseRotate))
counterClockwiseRotationButton?.setImage(ToolBarButtonImageBuilder.rotateCCWImage(), for: .normal)
let icon = iconProvider?.getCounterClockwiseRotationIcon() ?? ToolBarButtonImageBuilder.rotateCCWImage()
counterClockwiseRotationButton?.setImage(icon, for: .normal)
}

private func createClockwiseRotationButton() {
clockwiseRotationButton = createOptionButton(withTitle: nil, andAction: #selector(clockwiseRotate))
clockwiseRotationButton?.setImage(ToolBarButtonImageBuilder.rotateCWImage(), for: .normal)
let icon = iconProvider?.getClockwiseRotationIcon() ?? ToolBarButtonImageBuilder.rotateCWImage()
clockwiseRotationButton?.setImage(icon, for: .normal)
}

private func createAlterCropper90DegreeButton() {
alterCropper90DegreeButton = createOptionButton(withTitle: nil, andAction: #selector(alterCropper90Degree))
alterCropper90DegreeButton?.setImage(ToolBarButtonImageBuilder.alterCropper90DegreeImage(), for: .normal)
let icon = iconProvider?.getAlterCropper90DegreeIcon() ?? ToolBarButtonImageBuilder.alterCropper90DegreeImage()
alterCropper90DegreeButton?.setImage(icon, for: .normal)
}

private func createResetButton(with image: UIImage? = nil) {
Expand All @@ -88,7 +92,8 @@ public class CropToolbar: UIView, CropToolbarProtocol {

private func createSetRatioButton() {
fixedRatioSettingButton = createOptionButton(withTitle: nil, andAction: #selector(setRatio))
fixedRatioSettingButton?.setImage(ToolBarButtonImageBuilder.clampImage(), for: .normal)
let icon = iconProvider?.getSetRatioIcon() ?? ToolBarButtonImageBuilder.clampImage()
fixedRatioSettingButton?.setImage(icon, for: .normal)
}

private func createCropButton() {
Expand Down Expand Up @@ -160,7 +165,8 @@ public class CropToolbar: UIView, CropToolbarProtocol {
}

if config.toolbarButtonOptions.contains(.reset) {
createResetButton(with: ToolBarButtonImageBuilder.resetImage())
let icon = iconProvider?.getResetIcon() ?? ToolBarButtonImageBuilder.resetImage()
createResetButton(with: icon)
addButtonsToContainer(button: resetButton)
resetButton?.isHidden = true
}
Expand Down
24 changes: 21 additions & 3 deletions Sources/Mantis/CropViewController/CropToolbarProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,28 @@ public protocol CropToolbarDelegate: AnyObject {
func didSelectAlterCropper90Degree()
}

public protocol CropToolbarIconProvider: AnyObject {
func getClockwiseRotationIcon() -> UIImage?
func getCounterClockwiseRotationIcon() -> UIImage?
func getResetIcon() -> UIImage?
func getSetRatioIcon() -> UIImage?
func getAlterCropper90DegreeIcon() -> UIImage?
}

public extension CropToolbarIconProvider {
func getClockwiseRotationIcon() -> UIImage? { return nil }
func getCounterClockwiseRotationIcon() -> UIImage? { return nil }
func getResetIcon() -> UIImage? { return nil }
func getSetRatioIcon() -> UIImage? { return nil }
func getAlterCropper90DegreeIcon() -> UIImage? { return nil }
}

public protocol CropToolbarProtocol: UIView {
var heightForVerticalOrientationConstraint: NSLayoutConstraint? {get set}
var widthForHorizonOrientationConstraint: NSLayoutConstraint? {get set}
var cropToolbarDelegate: CropToolbarDelegate? {get set}
var heightForVerticalOrientationConstraint: NSLayoutConstraint? { get set }
var widthForHorizonOrientationConstraint: NSLayoutConstraint? { get set }
var cropToolbarDelegate: CropToolbarDelegate? { get set }

var iconProvider: CropToolbarIconProvider? { get set }

func createToolbarUI(config: CropToolbarConfig)
func handleFixedRatioSetted(ratio: Double)
Expand Down
179 changes: 5 additions & 174 deletions Sources/Mantis/CropViewController/ToolBarButtonImageBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,118 +30,15 @@ import UIKit

struct ToolBarButtonImageBuilder {
static func rotateCCWImage() -> UIImage? {
var rotateImage: UIImage? = nil

UIGraphicsBeginImageContextWithOptions(CGSize(width: 18, height: 21), false, 0.0)

//// Draw rectangle
let rectanglePath = UIBezierPath(rect: CGRect(x: 0, y: 9, width: 12, height: 12))
UIColor.white.setFill()
rectanglePath.fill()

//// Draw triangle
let trianglePath = UIBezierPath()
trianglePath.move(to: CGPoint(x: 5, y: 3))
trianglePath.addLine(to: CGPoint(x: 10, y: 6))
trianglePath.addLine(to: CGPoint(x: 10, y: 0))
trianglePath.addLine(to: CGPoint(x: 5, y: 3))
trianglePath.close()
UIColor.white.setFill()
trianglePath.fill()

//// Bezier Drawing
let bezierPath = UIBezierPath()
bezierPath.move(to: CGPoint(x: 10, y: 3))

bezierPath.addCurve(to: CGPoint(x: 17.5, y: 11), controlPoint1: CGPoint(x: 15, y: 3), controlPoint2: CGPoint(x: 17.5, y: 5.91))
UIColor.white.setStroke()
bezierPath.lineWidth = 1
bezierPath.stroke()
rotateImage = UIGraphicsGetImageFromCurrentImageContext()

UIGraphicsEndImageContext()

return rotateImage
return UIImage(systemName: "rotate.left")
}

static func rotateCWImage() -> UIImage? {
guard let rotateCCWImage = self.rotateCCWImage(), let cgImage = rotateCCWImage.cgImage else { return nil }

UIGraphicsBeginImageContextWithOptions(rotateCCWImage.size, false, rotateCCWImage.scale)
let context = UIGraphicsGetCurrentContext()
context?.translateBy(x: rotateCCWImage.size.width, y: rotateCCWImage.size.height)
context?.rotate(by: .pi)
context?.draw(cgImage, in: CGRect(x: 0, y: 0, width: rotateCCWImage.size.width, height: rotateCCWImage.size.height))
let rotateCWImage: UIImage? = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return rotateCWImage
return UIImage(systemName: "rotate.right")
}

static func flipHorizontally() -> UIImage? {
var flippedImage: UIImage? = nil

let wholeWidth = 24
let wholeHeight = 24
UIGraphicsBeginImageContextWithOptions(CGSize(width: wholeWidth, height: wholeHeight), false, 0.0)

let arrowWidth = 5
let arrowHeight = 6
let topbarWidth = wholeWidth - arrowWidth
let topbarY = arrowHeight / 2 - 1

// topbar
let rectangle2Path = UIBezierPath(rect: CGRect(x: 0, y: topbarY, width: topbarWidth, height: 1))
UIColor.white.setFill()
rectangle2Path.fill()

// left arrow
let leftarrowPath = UIBezierPath()
leftarrowPath.move(to: CGPoint(x: 0, y: topbarY))
leftarrowPath.addLine(to: CGPoint(x: arrowWidth, y: 0))
leftarrowPath.addLine(to: CGPoint(x: arrowWidth, y: arrowHeight))
leftarrowPath.addLine(to: CGPoint(x: 0, y: topbarY))
leftarrowPath.close()
UIColor.white.setFill()
leftarrowPath.fill()

// right arrow
let rightarrowPath = UIBezierPath()
rightarrowPath.move(to: CGPoint(x: wholeWidth, y: topbarY))
rightarrowPath.addLine(to: CGPoint(x: wholeWidth - arrowWidth, y: 0))
rightarrowPath.addLine(to: CGPoint(x: wholeWidth - arrowWidth, y: arrowHeight))
rightarrowPath.addLine(to: CGPoint(x: wholeWidth, y: topbarY))
rightarrowPath.close()
UIColor.white.setFill()
rightarrowPath.fill()

let mirrorWidth = wholeWidth / 2 - 1
let mirrowHeight = wholeHeight - 8

// left mirror
let leftMirror = UIBezierPath()
leftMirror.move(to: CGPoint(x: 0, y: wholeHeight))
leftMirror.addLine(to: CGPoint(x: mirrorWidth, y: wholeHeight))
leftMirror.addLine(to: CGPoint(x: mirrorWidth, y: wholeHeight - mirrowHeight))
leftMirror.addLine(to: CGPoint(x: 0, y: wholeHeight))
leftMirror.close()
UIColor.white.setFill()
leftMirror.fill()

// right mirror
let rightMirror = UIBezierPath()
rightMirror.move(to: CGPoint(x: wholeWidth, y: wholeHeight))
rightMirror.addLine(to: CGPoint(x: wholeWidth - mirrorWidth, y: wholeHeight))
rightMirror.addLine(to: CGPoint(x: wholeWidth - mirrorWidth, y: wholeHeight - mirrowHeight))
rightMirror.addLine(to: CGPoint(x: wholeWidth, y: wholeHeight))
rightMirror.close()
UIColor.white.setFill()
rightMirror.fill()

flippedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

return flippedImage

UIImage(systemName: "flip.horizontal")
}

static func flipVertically() -> UIImage? {
Expand All @@ -158,77 +55,11 @@ struct ToolBarButtonImageBuilder {
}

static func clampImage() -> UIImage? {
var clampImage: UIImage? = nil

UIGraphicsBeginImageContextWithOptions(CGSize(width: 22, height: 16), false, 0.0)

//// Color Declarations
let outerBox = UIColor(red: 1, green: 1, blue: 1, alpha: 0.553)
let innerBox = UIColor(red: 1, green: 1, blue: 1, alpha: 0.773)

//// Rectangle Drawing
let rectanglePath = UIBezierPath(rect: CGRect(x: 0, y: 3, width: 13, height: 13))
UIColor.white.setFill()
rectanglePath.fill()


//// Outer
//// Top Drawing
let topPath = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 22, height: 2))
outerBox.setFill()
topPath.fill()

//// Side Drawing
let sidePath = UIBezierPath(rect: CGRect(x: 19, y: 2, width: 3, height: 14))
outerBox.setFill()
sidePath.fill()

//// Rectangle 2 Drawing
let rectangle2Path = UIBezierPath(rect: CGRect(x: 14, y: 3, width: 4, height: 13))
innerBox.setFill()
rectangle2Path.fill()

clampImage = UIGraphicsGetImageFromCurrentImageContext()

UIGraphicsEndImageContext()
return clampImage
return UIImage(systemName: "aspectratio")
}

static func resetImage() -> UIImage? {
var resetImage: UIImage? = nil

UIGraphicsBeginImageContextWithOptions(CGSize(width: 22, height: 18), false, 0.0) //// Bezier 2 Drawing
let bezier2Path = UIBezierPath()
bezier2Path.move(to: CGPoint(x: 22, y: 9))
bezier2Path.addCurve(to: CGPoint(x: 13, y: 18), controlPoint1: CGPoint(x: 22, y: 13.97), controlPoint2: CGPoint(x: 17.97, y: 18))
bezier2Path.addCurve(to: CGPoint(x: 13, y: 16), controlPoint1: CGPoint(x: 13, y: 17.35), controlPoint2: CGPoint(x: 13, y: 16.68))
bezier2Path.addCurve(to: CGPoint(x: 20, y: 9), controlPoint1: CGPoint(x: 16.87, y: 16), controlPoint2: CGPoint(x: 20, y: 12.87))
bezier2Path.addCurve(to: CGPoint(x: 13, y: 2), controlPoint1: CGPoint(x: 20, y: 5.13), controlPoint2: CGPoint(x: 16.87, y: 2))
bezier2Path.addCurve(to: CGPoint(x: 6.55, y: 6.27), controlPoint1: CGPoint(x: 10.1, y: 2), controlPoint2: CGPoint(x: 7.62, y: 3.76))
bezier2Path.addCurve(to: CGPoint(x: 6, y: 9), controlPoint1: CGPoint(x: 6.2, y: 7.11), controlPoint2: CGPoint(x: 6, y: 8.03))
bezier2Path.addLine(to: CGPoint(x: 4, y: 9))
bezier2Path.addCurve(to: CGPoint(x: 4.65, y: 5.63), controlPoint1: CGPoint(x: 4, y: 7.81), controlPoint2: CGPoint(x: 4.23, y: 6.67))
bezier2Path.addCurve(to: CGPoint(x: 7.65, y: 1.76), controlPoint1: CGPoint(x: 5.28, y: 4.08), controlPoint2: CGPoint(x: 6.32, y: 2.74))
bezier2Path.addCurve(to: CGPoint(x: 13, y: 0), controlPoint1: CGPoint(x: 9.15, y: 0.65), controlPoint2: CGPoint(x: 11, y: 0))
bezier2Path.addCurve(to: CGPoint(x: 22, y: 9), controlPoint1: CGPoint(x: 17.97, y: 0), controlPoint2: CGPoint(x: 22, y: 4.03))
bezier2Path.close()
UIColor.white.setFill()
bezier2Path.fill()

//// Polygon Drawing
let polygonPath = UIBezierPath()
polygonPath.move(to: CGPoint(x: 5, y: 15))
polygonPath.addLine(to: CGPoint(x: 10, y: 9))
polygonPath.addLine(to: CGPoint(x: 0, y: 9))
polygonPath.addLine(to: CGPoint(x: 5, y: 15))
polygonPath.close()
UIColor.white.setFill()
polygonPath.fill()

resetImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

return resetImage
return UIImage(systemName: "arrow.2.circlepath")
}

static func alterCropper90DegreeImage() -> UIImage? {
Expand Down

0 comments on commit 42b89cd

Please sign in to comment.