diff --git a/.gitignore b/.gitignore index 488ce14..2b7a934 100644 --- a/.gitignore +++ b/.gitignore @@ -46,8 +46,7 @@ playground.xcworkspace # you should judge for yourself, the pros and cons are mentioned at: # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control # -Pods/ -*.lock +# Pods/ # Carthage # diff --git a/README.md b/README.md index f03cafe..c089585 100644 --- a/README.md +++ b/README.md @@ -132,16 +132,10 @@ class ViewController: UIViewController, YPSignatureDelegate { ## Example Project -Check out the example project for more information on how to save signatures and how to clear the signature view. -First you need run `pod install` to install the dependency. - +Check out the example project for more information on how to save signatures and how to clear the signature view. ## Installation -### Cocoapods -`pod 'YPDrawSignatureView'` - -### Manual Add YPDrawSignature.swift to your project ## Support and Issues diff --git a/SignatureTest/Podfile b/SignatureTest/Podfile deleted file mode 100755 index 0f58288..0000000 --- a/SignatureTest/Podfile +++ /dev/null @@ -1,11 +0,0 @@ -source 'https://github.com/CocoaPods/Specs.git' -platform :ios, '9.0' -use_frameworks! - -target 'SignatureTest' do - pod 'YPDrawSignatureView', :path => '../' - - target 'SignatureTestTests' do - end - -end diff --git a/SignatureTest/SignatureTest.xcodeproj/project.pbxproj b/SignatureTest/SignatureTest.xcodeproj/project.pbxproj index 468bc6b..4df3945 100644 --- a/SignatureTest/SignatureTest.xcodeproj/project.pbxproj +++ b/SignatureTest/SignatureTest.xcodeproj/project.pbxproj @@ -7,14 +7,13 @@ objects = { /* Begin PBXBuildFile section */ - 38D085A874F3194E248713CB /* Pods_SignatureTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6926F0FADCA5FB71766A628E /* Pods_SignatureTest.framework */; }; 4BE489E91C252F8B00741EAD /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE489E81C252F8B00741EAD /* AppDelegate.swift */; }; 4BE489EB1C252F8B00741EAD /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE489EA1C252F8B00741EAD /* ViewController.swift */; }; 4BE489EE1C252F8B00741EAD /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4BE489EC1C252F8B00741EAD /* Main.storyboard */; }; 4BE489F01C252F8B00741EAD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4BE489EF1C252F8B00741EAD /* Assets.xcassets */; }; 4BE489F31C252F8B00741EAD /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4BE489F11C252F8B00741EAD /* LaunchScreen.storyboard */; }; 4BE48A091C252F8F00741EAD /* SignatureTestUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE48A081C252F8F00741EAD /* SignatureTestUITests.swift */; }; - 524D87FF259748340F5FA465 /* Pods_SignatureTest_SignatureTestTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 32CDB68CC74CB6FFDB72DFE6 /* Pods_SignatureTest_SignatureTestTests.framework */; }; + 4BE48A171C252FC600741EAD /* YPDrawSignatureView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE48A161C252FC600741EAD /* YPDrawSignatureView.swift */; }; EACD35371EB929F000C20EF8 /* SignatureViewTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = EACD35361EB929F000C20EF8 /* SignatureViewTest.swift */; }; /* End PBXBuildFile section */ @@ -36,9 +35,6 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 2689FA011CB840F16CF753C1 /* Pods-SignatureTest.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SignatureTest.release.xcconfig"; path = "Pods/Target Support Files/Pods-SignatureTest/Pods-SignatureTest.release.xcconfig"; sourceTree = ""; }; - 32CDB68CC74CB6FFDB72DFE6 /* Pods_SignatureTest_SignatureTestTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SignatureTest_SignatureTestTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B8389853E4439C3E4C113E1 /* Pods-SignatureTest.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SignatureTest.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SignatureTest/Pods-SignatureTest.debug.xcconfig"; sourceTree = ""; }; 4BE489E51C252F8B00741EAD /* SignatureTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SignatureTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BE489E81C252F8B00741EAD /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 4BE489EA1C252F8B00741EAD /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; @@ -51,9 +47,7 @@ 4BE48A041C252F8F00741EAD /* SignatureTestUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SignatureTestUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 4BE48A081C252F8F00741EAD /* SignatureTestUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignatureTestUITests.swift; sourceTree = ""; }; 4BE48A0A1C252F8F00741EAD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 6926F0FADCA5FB71766A628E /* Pods_SignatureTest.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SignatureTest.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 6CAB83425D2E571B94BB80F8 /* Pods-SignatureTest-SignatureTestTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SignatureTest-SignatureTestTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SignatureTest-SignatureTestTests/Pods-SignatureTest-SignatureTestTests.debug.xcconfig"; sourceTree = ""; }; - CC9F5A8A313C03E47CEF0C82 /* Pods-SignatureTest-SignatureTestTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SignatureTest-SignatureTestTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-SignatureTest-SignatureTestTests/Pods-SignatureTest-SignatureTestTests.release.xcconfig"; sourceTree = ""; }; + 4BE48A161C252FC600741EAD /* YPDrawSignatureView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = YPDrawSignatureView.swift; sourceTree = ""; }; EACD35361EB929F000C20EF8 /* SignatureViewTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignatureViewTest.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -62,7 +56,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 38D085A874F3194E248713CB /* Pods_SignatureTest.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -70,7 +63,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 524D87FF259748340F5FA465 /* Pods_SignatureTest_SignatureTestTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -91,8 +83,6 @@ 4BE489FC1C252F8E00741EAD /* SignatureTestTests */, 4BE48A071C252F8F00741EAD /* SignatureTestUITests */, 4BE489E61C252F8B00741EAD /* Products */, - 6E53A5932BB74833A9D7E912 /* Pods */, - 4FAC73E521F9E4A750A4A83E /* Frameworks */, ); sourceTree = ""; }; @@ -115,6 +105,7 @@ 4BE489EF1C252F8B00741EAD /* Assets.xcassets */, 4BE489F11C252F8B00741EAD /* LaunchScreen.storyboard */, 4BE489F41C252F8C00741EAD /* Info.plist */, + 4BE48A161C252FC600741EAD /* YPDrawSignatureView.swift */, ); path = SignatureTest; sourceTree = ""; @@ -137,26 +128,6 @@ path = SignatureTestUITests; sourceTree = ""; }; - 4FAC73E521F9E4A750A4A83E /* Frameworks */ = { - isa = PBXGroup; - children = ( - 6926F0FADCA5FB71766A628E /* Pods_SignatureTest.framework */, - 32CDB68CC74CB6FFDB72DFE6 /* Pods_SignatureTest_SignatureTestTests.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 6E53A5932BB74833A9D7E912 /* Pods */ = { - isa = PBXGroup; - children = ( - 3B8389853E4439C3E4C113E1 /* Pods-SignatureTest.debug.xcconfig */, - 2689FA011CB840F16CF753C1 /* Pods-SignatureTest.release.xcconfig */, - 6CAB83425D2E571B94BB80F8 /* Pods-SignatureTest-SignatureTestTests.debug.xcconfig */, - CC9F5A8A313C03E47CEF0C82 /* Pods-SignatureTest-SignatureTestTests.release.xcconfig */, - ); - name = Pods; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -164,12 +135,9 @@ isa = PBXNativeTarget; buildConfigurationList = 4BE48A0D1C252F8F00741EAD /* Build configuration list for PBXNativeTarget "SignatureTest" */; buildPhases = ( - 6EE9061E2949BBF179801657 /* [CP] Check Pods Manifest.lock */, 4BE489E11C252F8B00741EAD /* Sources */, 4BE489E21C252F8B00741EAD /* Frameworks */, 4BE489E31C252F8B00741EAD /* Resources */, - AD60F11A842DB590AB63ACE2 /* [CP] Embed Pods Frameworks */, - F29FC13F3EDB8ECEFD904073 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -184,12 +152,9 @@ isa = PBXNativeTarget; buildConfigurationList = 4BE48A101C252F8F00741EAD /* Build configuration list for PBXNativeTarget "SignatureTestTests" */; buildPhases = ( - 3BCFDBDC14AFBCD5E46F74C3 /* [CP] Check Pods Manifest.lock */, 4BE489F51C252F8E00741EAD /* Sources */, 4BE489F61C252F8E00741EAD /* Frameworks */, 4BE489F71C252F8E00741EAD /* Resources */, - 393459C3B158B24D73110726 /* [CP] Embed Pods Frameworks */, - 77FF6599AD03EC611456C887 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -293,99 +258,6 @@ }; /* End PBXResourcesBuildPhase section */ -/* Begin PBXShellScriptBuildPhase section */ - 393459C3B158B24D73110726 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SignatureTest-SignatureTestTests/Pods-SignatureTest-SignatureTestTests-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - 3BCFDBDC14AFBCD5E46F74C3 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; - showEnvVarsInLog = 0; - }; - 6EE9061E2949BBF179801657 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; - showEnvVarsInLog = 0; - }; - 77FF6599AD03EC611456C887 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SignatureTest-SignatureTestTests/Pods-SignatureTest-SignatureTestTests-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - AD60F11A842DB590AB63ACE2 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SignatureTest/Pods-SignatureTest-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - F29FC13F3EDB8ECEFD904073 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SignatureTest/Pods-SignatureTest-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - /* Begin PBXSourcesBuildPhase section */ 4BE489E11C252F8B00741EAD /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -393,6 +265,7 @@ files = ( 4BE489EB1C252F8B00741EAD /* ViewController.swift in Sources */, 4BE489E91C252F8B00741EAD /* AppDelegate.swift in Sources */, + 4BE48A171C252FC600741EAD /* YPDrawSignatureView.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -536,7 +409,6 @@ }; 4BE48A0E1C252F8F00741EAD /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3B8389853E4439C3E4C113E1 /* Pods-SignatureTest.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; DEVELOPMENT_TEAM = ""; @@ -550,7 +422,6 @@ }; 4BE48A0F1C252F8F00741EAD /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 2689FA011CB840F16CF753C1 /* Pods-SignatureTest.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; DEVELOPMENT_TEAM = ""; @@ -565,7 +436,6 @@ }; 4BE48A111C252F8F00741EAD /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 6CAB83425D2E571B94BB80F8 /* Pods-SignatureTest-SignatureTestTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; DEVELOPMENT_TEAM = 784F7MSSDM; @@ -580,7 +450,6 @@ }; 4BE48A121C252F8F00741EAD /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = CC9F5A8A313C03E47CEF0C82 /* Pods-SignatureTest-SignatureTestTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; DEVELOPMENT_TEAM = 784F7MSSDM; diff --git a/SignatureTest/SignatureTest.xcworkspace/contents.xcworkspacedata b/SignatureTest/SignatureTest.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index e64c436..0000000 --- a/SignatureTest/SignatureTest.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/SignatureTest/SignatureTest/Base.lproj/Main.storyboard b/SignatureTest/SignatureTest/Base.lproj/Main.storyboard index 5c28e97..be00631 100644 --- a/SignatureTest/SignatureTest/Base.lproj/Main.storyboard +++ b/SignatureTest/SignatureTest/Base.lproj/Main.storyboard @@ -1,11 +1,11 @@ - + - + @@ -24,7 +24,7 @@ - + @@ -35,12 +35,6 @@ - - - - - - diff --git a/SignatureTest/SignatureTest/ViewController.swift b/SignatureTest/SignatureTest/ViewController.swift index 80501f4..e61854d 100644 --- a/SignatureTest/SignatureTest/ViewController.swift +++ b/SignatureTest/SignatureTest/ViewController.swift @@ -8,7 +8,6 @@ // https://github.com/GJNilsen/YPDrawSignatureView/blob/master/README.md Project Contributors import UIKit -import YPDrawSignatureView class ViewController: UIViewController, YPSignatureDelegate { diff --git a/SignatureTest/SignatureTest/YPDrawSignatureView.swift b/SignatureTest/SignatureTest/YPDrawSignatureView.swift new file mode 100644 index 0000000..1e26b38 --- /dev/null +++ b/SignatureTest/SignatureTest/YPDrawSignatureView.swift @@ -0,0 +1,232 @@ +// YPDrawSignatureView is open source +// Version 1.1.2 +// +// Copyright (c) 2014 - 2017 The YPDrawSignatureView Project Contributors +// Available under the MIT license +// +// https://github.com/GJNilsen/YPDrawSignatureView/blob/master/LICENSE License Information +// https://github.com/GJNilsen/YPDrawSignatureView/blob/master/README.md Project Contributors + +import UIKit +import CoreGraphics + +// MARK: Class properties and initialization +/// # Class: YPDrawSignatureView +/// Accepts touches and draws an image to an UIView +/// ## Description +/// This is an UIView based class for capturing a signature drawn by a finger in iOS. +/// ## Usage +/// Add the YPSignatureDelegate to the view to exploit the optional delegate methods +/// - startedDrawing() +/// - finishedDrawing() +/// - Add an @IBOutlet, and set its delegate to self +/// - Clear the signature field by calling clear() to it +/// - Retrieve the signature from the field by either calling +/// - getSignature() or +/// - getCroppedSignature() +@IBDesignable +final public class YPDrawSignatureView: UIView { + + weak var delegate: YPSignatureDelegate? + + // MARK: - Public properties + @IBInspectable public var strokeWidth: CGFloat = 2.0 { + didSet { + path.lineWidth = strokeWidth + } + } + + @IBInspectable public var strokeColor: UIColor = .black { + didSet { + strokeColor.setStroke() + } + } + + @objc + @available(*, deprecated, renamed: "backgroundColor") + @IBInspectable public var signatureBackgroundColor: UIColor = .white { + didSet { + backgroundColor = signatureBackgroundColor + } + } + + // Computed Property returns true if the view actually contains a signature + public var doesContainSignature: Bool { + get { + if path.isEmpty { + return false + } else { + return true + } + } + } + + // MARK: - Private properties + fileprivate var path = UIBezierPath() + fileprivate var points = [CGPoint](repeating: CGPoint(), count: 5) + fileprivate var controlPoint = 0 + + // MARK: - Init + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + + path.lineWidth = strokeWidth + path.lineJoinStyle = .round + path.lineCapStyle = .round + } + + override public init(frame: CGRect) { + super.init(frame: frame) + + path.lineWidth = strokeWidth + path.lineJoinStyle = .round + path.lineCapStyle = .round + } + + // MARK: - Draw + override public func draw(_ rect: CGRect) { + self.strokeColor.setStroke() + self.path.stroke() + } + + // MARK: - Touch handling functions + override public func touchesBegan(_ touches: Set , with event: UIEvent?) { + if let firstTouch = touches.first { + let touchPoint = firstTouch.location(in: self) + controlPoint = 0 + points[0] = touchPoint + } + + if let delegate = delegate { + delegate.didStart() + } + } + + override public func touchesMoved(_ touches: Set , with event: UIEvent?) { + if let firstTouch = touches.first { + let touchPoint = firstTouch.location(in: self) + controlPoint += 1 + points[controlPoint] = touchPoint + if (controlPoint == 4) { + points[3] = CGPoint(x: (points[2].x + points[4].x)/2.0, y: (points[2].y + points[4].y)/2.0) + path.move(to: points[0]) + path.addCurve(to: points[3], controlPoint1: points[1], controlPoint2: points[2]) + + setNeedsDisplay() + points[0] = points[3] + points[1] = points[4] + controlPoint = 1 + } + + setNeedsDisplay() + } + } + + override public func touchesEnded(_ touches: Set , with event: UIEvent?) { + if controlPoint < 4 { + let touchPoint = points[0] + path.move(to: CGPoint(x: touchPoint.x,y: touchPoint.y)) + path.addLine(to: CGPoint(x: touchPoint.x,y: touchPoint.y)) + setNeedsDisplay() + } else { + controlPoint = 0 + } + + if let delegate = delegate { + delegate.didFinish() + } + } + + // MARK: - Methods for interacting with Signature View + + // Clear the Signature View + public func clear() { + self.path.removeAllPoints() + self.setNeedsDisplay() + } + + // Save the Signature as an UIImage + public func getSignature(scale:CGFloat = 1) -> UIImage? { + if !doesContainSignature { return nil } + UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, scale) + self.strokeColor.setStroke() + self.path.stroke() + let signature = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + return signature + } + + // Save the Signature (cropped of outside white space) as a UIImage + public func getCroppedSignature(scale:CGFloat = 1) -> UIImage? { + guard let fullRender = getSignature(scale:scale) else { return nil } + let bounds = self.scale(path.bounds.insetBy(dx: -strokeWidth/2, dy: -strokeWidth/2), byFactor: scale) + guard let imageRef = fullRender.cgImage?.cropping(to: bounds) else { return nil } + return UIImage(cgImage: imageRef) + } + + + fileprivate func scale(_ rect: CGRect, byFactor factor: CGFloat) -> CGRect + { + var scaledRect = rect + scaledRect.origin.x *= factor + scaledRect.origin.y *= factor + scaledRect.size.width *= factor + scaledRect.size.height *= factor + return scaledRect + } + + // Saves the Signature as a Vector PDF Data blob + public func getPDFSignature() -> Data { + + let mutableData = CFDataCreateMutable(nil, 0) + + guard let dataConsumer = CGDataConsumer.init(data: mutableData!) else { fatalError() } + + var rect = CGRect(x: 0, y: 0, width: frame.width, height: frame.height) + + guard let pdfContext = CGContext(consumer: dataConsumer, mediaBox: &rect, nil) else { fatalError() } + + pdfContext.beginPDFPage(nil) + pdfContext.translateBy(x: 0, y: frame.height) + pdfContext.scaleBy(x: 1, y: -1) + pdfContext.addPath(path.cgPath) + pdfContext.setStrokeColor(strokeColor.cgColor) + pdfContext.strokePath() + pdfContext.saveGState() + pdfContext.endPDFPage() + pdfContext.closePDF() + + let data = mutableData! as Data + + return data + } + + + // MARK: - Injection method for Unit Tests only + /// This method is used to inject a bezier path for testing + /// purposes only. This method is not included in the main + /// YPDrawSignatureView.swift source file by intention. + func injectBezierPath(_ path: UIBezierPath) { + self.path = path + } +} + +// MARK: - Protocol definition for YPDrawSignatureViewDelegate +/// ## YPDrawSignatureViewDelegate Protocol +/// YPDrawSignatureViewDelegate: +/// - optional didStart() +/// - optional didFinish() +@objc +protocol YPSignatureDelegate: class { + func didStart() + func didFinish() + @available(*, unavailable, renamed: "didFinish()") + func startedDrawing() + @available(*, unavailable, renamed: "didFinish()") + func finishedDrawing() +} + +extension YPSignatureDelegate { + func didStart() {} + func didFinish() {} +} diff --git a/Sources/YPDrawSignatureView.swift b/Sources/YPDrawSignatureView.swift index 6c92962..236f60b 100644 --- a/Sources/YPDrawSignatureView.swift +++ b/Sources/YPDrawSignatureView.swift @@ -25,9 +25,9 @@ import CoreGraphics /// - getSignature() or /// - getCroppedSignature() @IBDesignable -open class YPDrawSignatureView: UIView { +final public class YPDrawSignatureView: UIView { - open weak var delegate: YPSignatureDelegate? + weak var delegate: YPSignatureDelegate? // MARK: - Public properties @IBInspectable public var strokeWidth: CGFloat = 2.0 { @@ -84,13 +84,13 @@ open class YPDrawSignatureView: UIView { } // MARK: - Draw - override open func draw(_ rect: CGRect) { + override public func draw(_ rect: CGRect) { self.strokeColor.setStroke() self.path.stroke() } // MARK: - Touch handling functions - override open func touchesBegan(_ touches: Set , with event: UIEvent?) { + override public func touchesBegan(_ touches: Set , with event: UIEvent?) { if let firstTouch = touches.first { let touchPoint = firstTouch.location(in: self) controlPoint = 0 @@ -102,7 +102,7 @@ open class YPDrawSignatureView: UIView { } } - override open func touchesMoved(_ touches: Set , with event: UIEvent?) { + override public func touchesMoved(_ touches: Set , with event: UIEvent?) { if let firstTouch = touches.first { let touchPoint = firstTouch.location(in: self) controlPoint += 1 @@ -122,7 +122,7 @@ open class YPDrawSignatureView: UIView { } } - override open func touchesEnded(_ touches: Set , with event: UIEvent?) { + override public func touchesEnded(_ touches: Set , with event: UIEvent?) { if controlPoint < 4 { let touchPoint = points[0] path.move(to: CGPoint(x: touchPoint.x,y: touchPoint.y)) @@ -209,7 +209,7 @@ open class YPDrawSignatureView: UIView { /// - optional didStart() /// - optional didFinish() @objc -public protocol YPSignatureDelegate: class { +protocol YPSignatureDelegate: class { func didStart() func didFinish() @available(*, unavailable, renamed: "didFinish()") diff --git a/YPDrawSignatureView.podspec b/YPDrawSignatureView.podspec deleted file mode 100644 index 351ba21..0000000 --- a/YPDrawSignatureView.podspec +++ /dev/null @@ -1,16 +0,0 @@ -Pod::Spec.new do |s| - s.name = 'YPDrawSignatureView' - s.version = '1.1.2' - s.ios.deployment_target = '9.0' - s.license = { :type => 'MIT', :file => 'LICENSE' } - s.summary = 'Capture signature view in Swift and export it as a vector graphics or bitmap' - s.homepage = 'https://github.com/kArTeL/YPDrawSignatureView.git' - s.author = { 'GJ Nilsen' => 'gj.nilsen@yuppielabel.com' } - s.requires_arc = true - s.source = { - :git => 'https://github.com/GJNilsen/YPDrawSignatureView.git', - :branch => 'master', - :tag => s.version.to_s - } - s.source_files = 'Sources/*.swift' -end