├── .gitignore ├── .travis.yml ├── Assets ├── check.png ├── check@2x.png ├── check_disabled.png ├── check_disabled@2x.png ├── clear.png ├── clear@2x.png ├── clear_disabled.png └── clear_disabled@2x.png ├── CONTRIBUTING.md ├── Contract.podspec ├── Images ├── cover-v2.png └── demo.png ├── LICENSE.md ├── Pod ├── Demo │ ├── AppDelegate.swift │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── Info.plist │ ├── Pod-Bridging-Header.h │ └── ViewController.swift ├── Pod.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── Tests.xcscheme ├── Pod.xcworkspace │ └── contents.xcworkspacedata ├── Podfile ├── Podfile.lock └── Tests │ ├── Info.plist │ └── Tests.m ├── README.md └── Source ├── HYPContractViewController.h ├── HYPContractViewController.m ├── HYPSignatureViewController.h ├── HYPSignatureViewController.m ├── HYPSignaturesViewController.h ├── HYPSignaturesViewController.m ├── UIButton+HYPSignatureViewController.h └── UIButton+HYPSignatureViewController.m /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | .AppleDouble 4 | .LSOverride 5 | Icon 6 | ._* 7 | .Spotlight-V100 8 | .Trashes 9 | 10 | # Xcode 11 | # 12 | build/ 13 | *.pbxuser 14 | !default.pbxuser 15 | *.mode1v3 16 | !default.mode1v3 17 | *.mode2v3 18 | !default.mode2v3 19 | *.perspectivev3 20 | !default.perspectivev3 21 | xcuserdata 22 | *.xccheckout 23 | *.moved-aside 24 | DerivedData 25 | *.hmap 26 | *.ipa 27 | *.xcuserstate 28 | 29 | # CocoaPods 30 | Pods 31 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | before_install: 3 | - gem install cocoapods 4 | 5 | # Use when you don't have third party dependencies 6 | script: xctool -project Pod/Pod.xcodeproj -scheme Tests -sdk iphonesimulator build test 7 | 8 | # Use when you have third party dependencies (CocoaPods generates a workspace) 9 | # podfile: Pod/Podfile 10 | # script: xctool -workspace Pod/Pod.xcworkspace -scheme Tests -sdk iphonesimulator build test 11 | -------------------------------------------------------------------------------- /Assets/check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperoslo/Contract/b30308a370e042e78f5f51a3573fd4f47f28ce7e/Assets/check.png -------------------------------------------------------------------------------- /Assets/check@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperoslo/Contract/b30308a370e042e78f5f51a3573fd4f47f28ce7e/Assets/check@2x.png -------------------------------------------------------------------------------- /Assets/check_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperoslo/Contract/b30308a370e042e78f5f51a3573fd4f47f28ce7e/Assets/check_disabled.png -------------------------------------------------------------------------------- /Assets/check_disabled@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperoslo/Contract/b30308a370e042e78f5f51a3573fd4f47f28ce7e/Assets/check_disabled@2x.png -------------------------------------------------------------------------------- /Assets/clear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperoslo/Contract/b30308a370e042e78f5f51a3573fd4f47f28ce7e/Assets/clear.png -------------------------------------------------------------------------------- /Assets/clear@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperoslo/Contract/b30308a370e042e78f5f51a3573fd4f47f28ce7e/Assets/clear@2x.png -------------------------------------------------------------------------------- /Assets/clear_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperoslo/Contract/b30308a370e042e78f5f51a3573fd4f47f28ce7e/Assets/clear_disabled.png -------------------------------------------------------------------------------- /Assets/clear_disabled@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperoslo/Contract/b30308a370e042e78f5f51a3573fd4f47f28ce7e/Assets/clear_disabled@2x.png -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | GitHub Issues is for reporting bugs, discussing features and general feedback in **Contract**. Be sure to check our [documentation](http://cocoadocs.org/docsets/Contract), [FAQ](https://github.com/hyperoslo/Contract/wiki/FAQ) and [past issues](https://github.com/hyperoslo/Contract/issues?state=closed) before opening any new issues. 2 | 3 | If you are posting about a crash in your application, a stack trace is helpful, but additional context, in the form of code and explanation, is necessary to be of any use. 4 | -------------------------------------------------------------------------------- /Contract.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "Contract" 3 | s.summary = "The easiest way to sign your soul away" 4 | s.version = "0.1.0" 5 | s.homepage = "https://github.com/hyperoslo/Contract" 6 | s.license = 'MIT' 7 | s.author = { "Hyper Interaktiv AS" => "ios@hyper.no" } 8 | s.source = { :git => "https://github.com/hyperoslo/Contract.git", :tag => s.version.to_s } 9 | s.social_media_url = 'https://twitter.com/hyperoslo' 10 | s.platform = :ios, '7.0' 11 | s.requires_arc = true 12 | s.source_files = 'Source/**/*' 13 | s.resource_bundles = { 14 | 'Contract' => ['Assets/*.{png}'] 15 | } 16 | s.frameworks = 'UIKit' 17 | 18 | s.dependency 'Hex' 19 | s.dependency 'HYPWebView' 20 | s.dependency 'Signature' 21 | s.dependency 'UIButton-ANDYHighlighted' 22 | s.dependency 'UIViewController-HYPContainer' 23 | end 24 | -------------------------------------------------------------------------------- /Images/cover-v2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperoslo/Contract/b30308a370e042e78f5f51a3573fd4f47f28ce7e/Images/cover-v2.png -------------------------------------------------------------------------------- /Images/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperoslo/Contract/b30308a370e042e78f5f51a3573fd4f47f28ce7e/Images/demo.png -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Licensed under the **MIT** license 2 | 3 | > Copyright (c) 2015 Hyper Interaktiv AS 4 | > 5 | > Permission is hereby granted, free of charge, to any person obtaining 6 | > a copy of this software and associated documentation files (the 7 | > "Software"), to deal in the Software without restriction, including 8 | > without limitation the rights to use, copy, modify, merge, publish, 9 | > distribute, sublicense, and/or sell copies of the Software, and to 10 | > permit persons to whom the Software is furnished to do so, subject to 11 | > the following conditions: 12 | > 13 | > The above copyright notice and this permission notice shall be 14 | > included in all copies or substantial portions of the Software. 15 | > 16 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | > EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | > MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | > IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | > CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | > TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | > SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /Pod/Demo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | @UIApplicationMain 4 | class AppDelegate: UIResponder, UIApplicationDelegate { 5 | 6 | var window: UIWindow? 7 | 8 | func application( 9 | application: UIApplication, 10 | didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 11 | window = UIWindow(frame: UIScreen.mainScreen().bounds) 12 | 13 | if let window = self.window { 14 | let requestURL = NSURL(string: "http://ga.berkeley.edu/wp-content/uploads/2015/02/pdf-sample.pdf") 15 | let request = NSURLRequest(URL: requestURL!) 16 | 17 | let contractController = ViewController( 18 | URLRequest: request, 19 | firstPartyName: "CEO", 20 | secondPartyName: "Michael Minion", 21 | needsSignature: true) 22 | 23 | let navigationController = UINavigationController(rootViewController: contractController) 24 | navigationController.toolbarHidden = false 25 | 26 | window.rootViewController = navigationController 27 | window.makeKeyAndVisible() 28 | } 29 | 30 | return true 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Pod/Demo/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /Pod/Demo/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "minimum-system-version" : "7.0", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "orientation" : "portrait", 11 | "idiom" : "iphone", 12 | "minimum-system-version" : "7.0", 13 | "subtype" : "retina4", 14 | "scale" : "2x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Pod/Demo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | no.hyper.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UIRequiredDeviceCapabilities 26 | 27 | armv7 28 | 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | 33 | UISupportedInterfaceOrientations~ipad 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | UIInterfaceOrientationPortraitUpsideDown 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Pod/Demo/Pod-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #ifndef Pod_Pod_Bridging_Header_h 2 | #define Pod_Pod_Bridging_Header_h 3 | 4 | #import "HYPContractViewController.h" 5 | #import "HYPSignaturesViewController.h" 6 | #import "HYPSignatureViewController.h" 7 | #import "UIButton+HYPSignatureViewController.h" 8 | #import "HYPSignatureView.h" 9 | #import "UIColor+Hex.h" 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /Pod/Demo/ViewController.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | class ViewController: HYPContractViewController, HYPContractViewControllerDelegate { 4 | 5 | override func viewDidLoad() { 6 | super.viewDidLoad() 7 | 8 | super.delegate = self 9 | } 10 | 11 | override func viewDidAppear(animated: Bool) { 12 | super.viewDidAppear(animated) 13 | 14 | updateButton(false) 15 | } 16 | 17 | func contractControllerDidSign( 18 | contractController: HYPContractViewController!, 19 | firstPartySignature: UIImage!, 20 | andSecondPartySignature secondPartySignature: UIImage!) { 21 | println("finished") 22 | } 23 | 24 | func contractController( 25 | contractController: HYPContractViewController!, 26 | didToogleSignatureControl shown: Bool) { 27 | updateButton(shown) 28 | } 29 | 30 | func updateButton(wasSigned: Bool) { 31 | let title = (wasSigned) ? "Hide control" : "Show control" 32 | let signButton = UIBarButtonItem( 33 | title: title, 34 | style: .Done, 35 | target: self, 36 | action: "toogleSignatureControl") 37 | toolbarItems = [signButton] 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Pod/Pod.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 140442281AE380F200DDB154 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 140442271AE380F200DDB154 /* AppDelegate.swift */; }; 11 | 1404422F1AE380F200DDB154 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1404422E1AE380F200DDB154 /* Images.xcassets */; }; 12 | 140442551AE381D100DDB154 /* HYPContractViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1404424A1AE381D100DDB154 /* HYPContractViewController.m */; }; 13 | 140442561AE381D100DDB154 /* HYPContractViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1404424A1AE381D100DDB154 /* HYPContractViewController.m */; }; 14 | 140442571AE381D100DDB154 /* HYPSignaturesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1404424C1AE381D100DDB154 /* HYPSignaturesViewController.m */; }; 15 | 140442581AE381D100DDB154 /* HYPSignaturesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1404424C1AE381D100DDB154 /* HYPSignaturesViewController.m */; }; 16 | 140442591AE381D100DDB154 /* HYPSignatureViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1404424E1AE381D100DDB154 /* HYPSignatureViewController.m */; }; 17 | 1404425A1AE381D100DDB154 /* HYPSignatureViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1404424E1AE381D100DDB154 /* HYPSignatureViewController.m */; }; 18 | 142B5EEA1AE6906200681B50 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 142B5EE91AE6906200681B50 /* ViewController.swift */; }; 19 | 142B5EED1AE697BC00681B50 /* UIButton+HYPSignatureViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 142B5EEC1AE697BC00681B50 /* UIButton+HYPSignatureViewController.m */; }; 20 | 146D72B31AB782920058798C /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 146D72B21AB782920058798C /* Tests.m */; }; 21 | 3F38CC73E16288496BC3BA04 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B2D144AD9458212465B413D6 /* libPods.a */; }; 22 | 90F1E95A651BED5951167FFA /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B2D144AD9458212465B413D6 /* libPods.a */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXFileReference section */ 26 | 140442231AE380F200DDB154 /* Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Demo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | 140442261AE380F200DDB154 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 28 | 140442271AE380F200DDB154 /* AppDelegate.swift */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; tabWidth = 2; }; 29 | 1404422E1AE380F200DDB154 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 30 | 140442491AE381D100DDB154 /* HYPContractViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HYPContractViewController.h; sourceTree = ""; }; 31 | 1404424A1AE381D100DDB154 /* HYPContractViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HYPContractViewController.m; sourceTree = ""; }; 32 | 1404424B1AE381D100DDB154 /* HYPSignaturesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HYPSignaturesViewController.h; sourceTree = ""; }; 33 | 1404424C1AE381D100DDB154 /* HYPSignaturesViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HYPSignaturesViewController.m; sourceTree = ""; }; 34 | 1404424D1AE381D100DDB154 /* HYPSignatureViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HYPSignatureViewController.h; sourceTree = ""; }; 35 | 1404424E1AE381D100DDB154 /* HYPSignatureViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HYPSignatureViewController.m; sourceTree = ""; }; 36 | 1404425F1AE381EE00DDB154 /* Pod-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Pod-Bridging-Header.h"; sourceTree = ""; }; 37 | 142B5EE91AE6906200681B50 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 38 | 142B5EEB1AE697BC00681B50 /* UIButton+HYPSignatureViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIButton+HYPSignatureViewController.h"; sourceTree = ""; }; 39 | 142B5EEC1AE697BC00681B50 /* UIButton+HYPSignatureViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIButton+HYPSignatureViewController.m"; sourceTree = ""; }; 40 | 146D72AC1AB782920058798C /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 146D72B11AB782920058798C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 42 | 146D72B21AB782920058798C /* Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Tests.m; sourceTree = ""; }; 43 | 14C136511AB784B200B7B07A /* .travis.yml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = .travis.yml; path = ../.travis.yml; sourceTree = ""; }; 44 | 14C136521AB784B200B7B07A /* CONTRIBUTING.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; name = CONTRIBUTING.md; path = ../CONTRIBUTING.md; sourceTree = ""; }; 45 | 14C136541AB784B200B7B07A /* LICENSE.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; name = LICENSE.md; path = ../LICENSE.md; sourceTree = ""; }; 46 | 14C136551AB784B200B7B07A /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; 47 | 80E49E48D416FCCDC5F94655 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; 48 | B2D144AD9458212465B413D6 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; 49 | C6E401A6A55AABEF0364681A /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; 50 | /* End PBXFileReference section */ 51 | 52 | /* Begin PBXFrameworksBuildPhase section */ 53 | 140442201AE380F200DDB154 /* Frameworks */ = { 54 | isa = PBXFrameworksBuildPhase; 55 | buildActionMask = 2147483647; 56 | files = ( 57 | 90F1E95A651BED5951167FFA /* libPods.a in Frameworks */, 58 | ); 59 | runOnlyForDeploymentPostprocessing = 0; 60 | }; 61 | 146D72A91AB782920058798C /* Frameworks */ = { 62 | isa = PBXFrameworksBuildPhase; 63 | buildActionMask = 2147483647; 64 | files = ( 65 | 3F38CC73E16288496BC3BA04 /* libPods.a in Frameworks */, 66 | ); 67 | runOnlyForDeploymentPostprocessing = 0; 68 | }; 69 | /* End PBXFrameworksBuildPhase section */ 70 | 71 | /* Begin PBXGroup section */ 72 | 09D58B42DCFC63F6E6D00A4E /* Pods */ = { 73 | isa = PBXGroup; 74 | children = ( 75 | 80E49E48D416FCCDC5F94655 /* Pods.debug.xcconfig */, 76 | C6E401A6A55AABEF0364681A /* Pods.release.xcconfig */, 77 | ); 78 | name = Pods; 79 | sourceTree = ""; 80 | }; 81 | 140442241AE380F200DDB154 /* Demo */ = { 82 | isa = PBXGroup; 83 | children = ( 84 | 140442271AE380F200DDB154 /* AppDelegate.swift */, 85 | 1404422E1AE380F200DDB154 /* Images.xcassets */, 86 | 140442251AE380F200DDB154 /* Supporting Files */, 87 | 1404425F1AE381EE00DDB154 /* Pod-Bridging-Header.h */, 88 | 142B5EE91AE6906200681B50 /* ViewController.swift */, 89 | ); 90 | path = Demo; 91 | sourceTree = ""; 92 | }; 93 | 140442251AE380F200DDB154 /* Supporting Files */ = { 94 | isa = PBXGroup; 95 | children = ( 96 | 140442261AE380F200DDB154 /* Info.plist */, 97 | ); 98 | name = "Supporting Files"; 99 | sourceTree = ""; 100 | }; 101 | 140442461AE381D100DDB154 /* Source */ = { 102 | isa = PBXGroup; 103 | children = ( 104 | 140442491AE381D100DDB154 /* HYPContractViewController.h */, 105 | 1404424A1AE381D100DDB154 /* HYPContractViewController.m */, 106 | 1404424B1AE381D100DDB154 /* HYPSignaturesViewController.h */, 107 | 1404424C1AE381D100DDB154 /* HYPSignaturesViewController.m */, 108 | 1404424D1AE381D100DDB154 /* HYPSignatureViewController.h */, 109 | 1404424E1AE381D100DDB154 /* HYPSignatureViewController.m */, 110 | 142B5EEB1AE697BC00681B50 /* UIButton+HYPSignatureViewController.h */, 111 | 142B5EEC1AE697BC00681B50 /* UIButton+HYPSignatureViewController.m */, 112 | ); 113 | name = Source; 114 | path = ../Source; 115 | sourceTree = ""; 116 | }; 117 | 146D728A1AB782920058798C = { 118 | isa = PBXGroup; 119 | children = ( 120 | 140442461AE381D100DDB154 /* Source */, 121 | 14C136501AB7849300B7B07A /* Metadata */, 122 | 146D72AF1AB782920058798C /* Tests */, 123 | 140442241AE380F200DDB154 /* Demo */, 124 | 146D72941AB782920058798C /* Products */, 125 | CE2D9DC45F5190C64EFB6C97 /* Frameworks */, 126 | 09D58B42DCFC63F6E6D00A4E /* Pods */, 127 | ); 128 | sourceTree = ""; 129 | }; 130 | 146D72941AB782920058798C /* Products */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 146D72AC1AB782920058798C /* Tests.xctest */, 134 | 140442231AE380F200DDB154 /* Demo.app */, 135 | ); 136 | name = Products; 137 | sourceTree = ""; 138 | }; 139 | 146D72AF1AB782920058798C /* Tests */ = { 140 | isa = PBXGroup; 141 | children = ( 142 | 146D72B21AB782920058798C /* Tests.m */, 143 | 146D72B01AB782920058798C /* Supporting Files */, 144 | ); 145 | path = Tests; 146 | sourceTree = ""; 147 | }; 148 | 146D72B01AB782920058798C /* Supporting Files */ = { 149 | isa = PBXGroup; 150 | children = ( 151 | 146D72B11AB782920058798C /* Info.plist */, 152 | ); 153 | name = "Supporting Files"; 154 | sourceTree = ""; 155 | }; 156 | 14C136501AB7849300B7B07A /* Metadata */ = { 157 | isa = PBXGroup; 158 | children = ( 159 | 14C136511AB784B200B7B07A /* .travis.yml */, 160 | 14C136521AB784B200B7B07A /* CONTRIBUTING.md */, 161 | 14C136541AB784B200B7B07A /* LICENSE.md */, 162 | 14C136551AB784B200B7B07A /* README.md */, 163 | ); 164 | name = Metadata; 165 | sourceTree = ""; 166 | }; 167 | CE2D9DC45F5190C64EFB6C97 /* Frameworks */ = { 168 | isa = PBXGroup; 169 | children = ( 170 | B2D144AD9458212465B413D6 /* libPods.a */, 171 | ); 172 | name = Frameworks; 173 | sourceTree = ""; 174 | }; 175 | /* End PBXGroup section */ 176 | 177 | /* Begin PBXNativeTarget section */ 178 | 140442221AE380F200DDB154 /* Demo */ = { 179 | isa = PBXNativeTarget; 180 | buildConfigurationList = 140442431AE380F200DDB154 /* Build configuration list for PBXNativeTarget "Demo" */; 181 | buildPhases = ( 182 | 76B0D973A366AF9108D5B670 /* Check Pods Manifest.lock */, 183 | 1404421F1AE380F200DDB154 /* Sources */, 184 | 140442201AE380F200DDB154 /* Frameworks */, 185 | 140442211AE380F200DDB154 /* Resources */, 186 | 50BD9BD60CC5077752B6506C /* Copy Pods Resources */, 187 | ); 188 | buildRules = ( 189 | ); 190 | dependencies = ( 191 | ); 192 | name = Demo; 193 | productName = Demo; 194 | productReference = 140442231AE380F200DDB154 /* Demo.app */; 195 | productType = "com.apple.product-type.application"; 196 | }; 197 | 146D72AB1AB782920058798C /* Tests */ = { 198 | isa = PBXNativeTarget; 199 | buildConfigurationList = 146D72B91AB782920058798C /* Build configuration list for PBXNativeTarget "Tests" */; 200 | buildPhases = ( 201 | 5D9952493E4CC399C97638E7 /* Check Pods Manifest.lock */, 202 | 146D72A81AB782920058798C /* Sources */, 203 | 146D72A91AB782920058798C /* Frameworks */, 204 | 146D72AA1AB782920058798C /* Resources */, 205 | B5D43FFB96B3223B5DD1D331 /* Copy Pods Resources */, 206 | ); 207 | buildRules = ( 208 | ); 209 | dependencies = ( 210 | ); 211 | name = Tests; 212 | productName = PodTests; 213 | productReference = 146D72AC1AB782920058798C /* Tests.xctest */; 214 | productType = "com.apple.product-type.bundle.unit-test"; 215 | }; 216 | /* End PBXNativeTarget section */ 217 | 218 | /* Begin PBXProject section */ 219 | 146D728B1AB782920058798C /* Project object */ = { 220 | isa = PBXProject; 221 | attributes = { 222 | LastUpgradeCheck = 0620; 223 | ORGANIZATIONNAME = Example; 224 | TargetAttributes = { 225 | 140442221AE380F200DDB154 = { 226 | CreatedOnToolsVersion = 6.3; 227 | }; 228 | 146D72AB1AB782920058798C = { 229 | CreatedOnToolsVersion = 6.2; 230 | }; 231 | }; 232 | }; 233 | buildConfigurationList = 146D728E1AB782920058798C /* Build configuration list for PBXProject "Pod" */; 234 | compatibilityVersion = "Xcode 3.2"; 235 | developmentRegion = English; 236 | hasScannedForEncodings = 0; 237 | knownRegions = ( 238 | en, 239 | Base, 240 | ); 241 | mainGroup = 146D728A1AB782920058798C; 242 | productRefGroup = 146D72941AB782920058798C /* Products */; 243 | projectDirPath = ""; 244 | projectRoot = ""; 245 | targets = ( 246 | 146D72AB1AB782920058798C /* Tests */, 247 | 140442221AE380F200DDB154 /* Demo */, 248 | ); 249 | }; 250 | /* End PBXProject section */ 251 | 252 | /* Begin PBXResourcesBuildPhase section */ 253 | 140442211AE380F200DDB154 /* Resources */ = { 254 | isa = PBXResourcesBuildPhase; 255 | buildActionMask = 2147483647; 256 | files = ( 257 | 1404422F1AE380F200DDB154 /* Images.xcassets in Resources */, 258 | ); 259 | runOnlyForDeploymentPostprocessing = 0; 260 | }; 261 | 146D72AA1AB782920058798C /* Resources */ = { 262 | isa = PBXResourcesBuildPhase; 263 | buildActionMask = 2147483647; 264 | files = ( 265 | ); 266 | runOnlyForDeploymentPostprocessing = 0; 267 | }; 268 | /* End PBXResourcesBuildPhase section */ 269 | 270 | /* Begin PBXShellScriptBuildPhase section */ 271 | 50BD9BD60CC5077752B6506C /* Copy Pods Resources */ = { 272 | isa = PBXShellScriptBuildPhase; 273 | buildActionMask = 2147483647; 274 | files = ( 275 | ); 276 | inputPaths = ( 277 | ); 278 | name = "Copy Pods Resources"; 279 | outputPaths = ( 280 | ); 281 | runOnlyForDeploymentPostprocessing = 0; 282 | shellPath = /bin/sh; 283 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n"; 284 | showEnvVarsInLog = 0; 285 | }; 286 | 5D9952493E4CC399C97638E7 /* Check Pods Manifest.lock */ = { 287 | isa = PBXShellScriptBuildPhase; 288 | buildActionMask = 2147483647; 289 | files = ( 290 | ); 291 | inputPaths = ( 292 | ); 293 | name = "Check Pods Manifest.lock"; 294 | outputPaths = ( 295 | ); 296 | runOnlyForDeploymentPostprocessing = 0; 297 | shellPath = /bin/sh; 298 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; 299 | showEnvVarsInLog = 0; 300 | }; 301 | 76B0D973A366AF9108D5B670 /* Check Pods Manifest.lock */ = { 302 | isa = PBXShellScriptBuildPhase; 303 | buildActionMask = 2147483647; 304 | files = ( 305 | ); 306 | inputPaths = ( 307 | ); 308 | name = "Check Pods Manifest.lock"; 309 | outputPaths = ( 310 | ); 311 | runOnlyForDeploymentPostprocessing = 0; 312 | shellPath = /bin/sh; 313 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; 314 | showEnvVarsInLog = 0; 315 | }; 316 | B5D43FFB96B3223B5DD1D331 /* Copy Pods Resources */ = { 317 | isa = PBXShellScriptBuildPhase; 318 | buildActionMask = 2147483647; 319 | files = ( 320 | ); 321 | inputPaths = ( 322 | ); 323 | name = "Copy Pods Resources"; 324 | outputPaths = ( 325 | ); 326 | runOnlyForDeploymentPostprocessing = 0; 327 | shellPath = /bin/sh; 328 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n"; 329 | showEnvVarsInLog = 0; 330 | }; 331 | /* End PBXShellScriptBuildPhase section */ 332 | 333 | /* Begin PBXSourcesBuildPhase section */ 334 | 1404421F1AE380F200DDB154 /* Sources */ = { 335 | isa = PBXSourcesBuildPhase; 336 | buildActionMask = 2147483647; 337 | files = ( 338 | 140442561AE381D100DDB154 /* HYPContractViewController.m in Sources */, 339 | 140442581AE381D100DDB154 /* HYPSignaturesViewController.m in Sources */, 340 | 140442281AE380F200DDB154 /* AppDelegate.swift in Sources */, 341 | 142B5EEA1AE6906200681B50 /* ViewController.swift in Sources */, 342 | 1404425A1AE381D100DDB154 /* HYPSignatureViewController.m in Sources */, 343 | ); 344 | runOnlyForDeploymentPostprocessing = 0; 345 | }; 346 | 146D72A81AB782920058798C /* Sources */ = { 347 | isa = PBXSourcesBuildPhase; 348 | buildActionMask = 2147483647; 349 | files = ( 350 | 146D72B31AB782920058798C /* Tests.m in Sources */, 351 | 140442571AE381D100DDB154 /* HYPSignaturesViewController.m in Sources */, 352 | 140442551AE381D100DDB154 /* HYPContractViewController.m in Sources */, 353 | 140442591AE381D100DDB154 /* HYPSignatureViewController.m in Sources */, 354 | 142B5EED1AE697BC00681B50 /* UIButton+HYPSignatureViewController.m in Sources */, 355 | ); 356 | runOnlyForDeploymentPostprocessing = 0; 357 | }; 358 | /* End PBXSourcesBuildPhase section */ 359 | 360 | /* Begin XCBuildConfiguration section */ 361 | 1404423F1AE380F200DDB154 /* Debug */ = { 362 | isa = XCBuildConfiguration; 363 | baseConfigurationReference = 80E49E48D416FCCDC5F94655 /* Pods.debug.xcconfig */; 364 | buildSettings = { 365 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 366 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 367 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 368 | GCC_NO_COMMON_BLOCKS = YES; 369 | GCC_PREPROCESSOR_DEFINITIONS = ( 370 | "DEBUG=1", 371 | "$(inherited)", 372 | ); 373 | INFOPLIST_FILE = Demo/Info.plist; 374 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 375 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 376 | PRODUCT_NAME = "$(TARGET_NAME)"; 377 | SWIFT_OBJC_BRIDGING_HEADER = "Demo/Pod-Bridging-Header.h"; 378 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 379 | TARGETED_DEVICE_FAMILY = 2; 380 | }; 381 | name = Debug; 382 | }; 383 | 140442401AE380F200DDB154 /* Release */ = { 384 | isa = XCBuildConfiguration; 385 | baseConfigurationReference = C6E401A6A55AABEF0364681A /* Pods.release.xcconfig */; 386 | buildSettings = { 387 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 388 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 389 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 390 | GCC_NO_COMMON_BLOCKS = YES; 391 | INFOPLIST_FILE = Demo/Info.plist; 392 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 393 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 394 | PRODUCT_NAME = "$(TARGET_NAME)"; 395 | SWIFT_OBJC_BRIDGING_HEADER = "Demo/Pod-Bridging-Header.h"; 396 | TARGETED_DEVICE_FAMILY = 2; 397 | }; 398 | name = Release; 399 | }; 400 | 146D72B41AB782920058798C /* Debug */ = { 401 | isa = XCBuildConfiguration; 402 | buildSettings = { 403 | ALWAYS_SEARCH_USER_PATHS = NO; 404 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 405 | CLANG_CXX_LIBRARY = "libc++"; 406 | CLANG_ENABLE_MODULES = YES; 407 | CLANG_ENABLE_OBJC_ARC = YES; 408 | CLANG_WARN_BOOL_CONVERSION = YES; 409 | CLANG_WARN_CONSTANT_CONVERSION = YES; 410 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 411 | CLANG_WARN_EMPTY_BODY = YES; 412 | CLANG_WARN_ENUM_CONVERSION = YES; 413 | CLANG_WARN_INT_CONVERSION = YES; 414 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 415 | CLANG_WARN_UNREACHABLE_CODE = YES; 416 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 417 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 418 | COPY_PHASE_STRIP = NO; 419 | ENABLE_STRICT_OBJC_MSGSEND = YES; 420 | GCC_C_LANGUAGE_STANDARD = gnu99; 421 | GCC_DYNAMIC_NO_PIC = NO; 422 | GCC_OPTIMIZATION_LEVEL = 0; 423 | GCC_PREPROCESSOR_DEFINITIONS = ( 424 | "DEBUG=1", 425 | "$(inherited)", 426 | ); 427 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 428 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 429 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 430 | GCC_WARN_UNDECLARED_SELECTOR = YES; 431 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 432 | GCC_WARN_UNUSED_FUNCTION = YES; 433 | GCC_WARN_UNUSED_VARIABLE = YES; 434 | IPHONEOS_DEPLOYMENT_TARGET = 8.2; 435 | MTL_ENABLE_DEBUG_INFO = YES; 436 | ONLY_ACTIVE_ARCH = YES; 437 | SDKROOT = iphoneos; 438 | }; 439 | name = Debug; 440 | }; 441 | 146D72B51AB782920058798C /* Release */ = { 442 | isa = XCBuildConfiguration; 443 | buildSettings = { 444 | ALWAYS_SEARCH_USER_PATHS = NO; 445 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 446 | CLANG_CXX_LIBRARY = "libc++"; 447 | CLANG_ENABLE_MODULES = YES; 448 | CLANG_ENABLE_OBJC_ARC = YES; 449 | CLANG_WARN_BOOL_CONVERSION = YES; 450 | CLANG_WARN_CONSTANT_CONVERSION = YES; 451 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 452 | CLANG_WARN_EMPTY_BODY = YES; 453 | CLANG_WARN_ENUM_CONVERSION = YES; 454 | CLANG_WARN_INT_CONVERSION = YES; 455 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 456 | CLANG_WARN_UNREACHABLE_CODE = YES; 457 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 458 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 459 | COPY_PHASE_STRIP = NO; 460 | ENABLE_NS_ASSERTIONS = NO; 461 | ENABLE_STRICT_OBJC_MSGSEND = YES; 462 | GCC_C_LANGUAGE_STANDARD = gnu99; 463 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 464 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 465 | GCC_WARN_UNDECLARED_SELECTOR = YES; 466 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 467 | GCC_WARN_UNUSED_FUNCTION = YES; 468 | GCC_WARN_UNUSED_VARIABLE = YES; 469 | IPHONEOS_DEPLOYMENT_TARGET = 8.2; 470 | MTL_ENABLE_DEBUG_INFO = NO; 471 | SDKROOT = iphoneos; 472 | VALIDATE_PRODUCT = YES; 473 | }; 474 | name = Release; 475 | }; 476 | 146D72BA1AB782920058798C /* Debug */ = { 477 | isa = XCBuildConfiguration; 478 | baseConfigurationReference = 80E49E48D416FCCDC5F94655 /* Pods.debug.xcconfig */; 479 | buildSettings = { 480 | FRAMEWORK_SEARCH_PATHS = ( 481 | "$(SDKROOT)/Developer/Library/Frameworks", 482 | "$(inherited)", 483 | ); 484 | GCC_PREPROCESSOR_DEFINITIONS = ( 485 | "DEBUG=1", 486 | "$(inherited)", 487 | ); 488 | INFOPLIST_FILE = Tests/Info.plist; 489 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 490 | PRODUCT_NAME = "$(TARGET_NAME)"; 491 | }; 492 | name = Debug; 493 | }; 494 | 146D72BB1AB782920058798C /* Release */ = { 495 | isa = XCBuildConfiguration; 496 | baseConfigurationReference = C6E401A6A55AABEF0364681A /* Pods.release.xcconfig */; 497 | buildSettings = { 498 | FRAMEWORK_SEARCH_PATHS = ( 499 | "$(SDKROOT)/Developer/Library/Frameworks", 500 | "$(inherited)", 501 | ); 502 | INFOPLIST_FILE = Tests/Info.plist; 503 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 504 | PRODUCT_NAME = "$(TARGET_NAME)"; 505 | }; 506 | name = Release; 507 | }; 508 | /* End XCBuildConfiguration section */ 509 | 510 | /* Begin XCConfigurationList section */ 511 | 140442431AE380F200DDB154 /* Build configuration list for PBXNativeTarget "Demo" */ = { 512 | isa = XCConfigurationList; 513 | buildConfigurations = ( 514 | 1404423F1AE380F200DDB154 /* Debug */, 515 | 140442401AE380F200DDB154 /* Release */, 516 | ); 517 | defaultConfigurationIsVisible = 0; 518 | defaultConfigurationName = Release; 519 | }; 520 | 146D728E1AB782920058798C /* Build configuration list for PBXProject "Pod" */ = { 521 | isa = XCConfigurationList; 522 | buildConfigurations = ( 523 | 146D72B41AB782920058798C /* Debug */, 524 | 146D72B51AB782920058798C /* Release */, 525 | ); 526 | defaultConfigurationIsVisible = 0; 527 | defaultConfigurationName = Release; 528 | }; 529 | 146D72B91AB782920058798C /* Build configuration list for PBXNativeTarget "Tests" */ = { 530 | isa = XCConfigurationList; 531 | buildConfigurations = ( 532 | 146D72BA1AB782920058798C /* Debug */, 533 | 146D72BB1AB782920058798C /* Release */, 534 | ); 535 | defaultConfigurationIsVisible = 0; 536 | defaultConfigurationName = Release; 537 | }; 538 | /* End XCConfigurationList section */ 539 | }; 540 | rootObject = 146D728B1AB782920058798C /* Project object */; 541 | } 542 | -------------------------------------------------------------------------------- /Pod/Pod.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Pod/Pod.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 61 | 62 | 68 | 69 | 70 | 71 | 72 | 73 | 79 | 80 | 86 | 87 | 88 | 89 | 91 | 92 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /Pod/Pod.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Pod/Podfile: -------------------------------------------------------------------------------- 1 | link_with 'Tests', 'Demo' 2 | 3 | pod 'HYPWebView' 4 | pod 'Signature' 5 | pod 'UIViewController-HYPContainer' 6 | pod 'Hex' 7 | pod 'UIButton-ANDYHighlighted' 8 | -------------------------------------------------------------------------------- /Pod/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Hex (1.1.1) 3 | - HYPWebView (0.1.0): 4 | - SVProgressHUD 5 | - Signature (0.1.0) 6 | - SVProgressHUD (1.1.3) 7 | - UIButton-ANDYHighlighted (0.2.1) 8 | - UIViewController-HYPContainer (0.2) 9 | 10 | DEPENDENCIES: 11 | - Hex 12 | - HYPWebView 13 | - Signature 14 | - UIButton-ANDYHighlighted 15 | - UIViewController-HYPContainer 16 | 17 | SPEC CHECKSUMS: 18 | Hex: acf6d0dc34658d3d44047a992bfd09190c87e6e7 19 | HYPWebView: 83b76c6481eb4f768f117605bb84b0ecb0b0111a 20 | Signature: e28a97a29066823dec37f13623015477a19bc60f 21 | SVProgressHUD: 748080e4f36e603f6c02aec292664239df5279c1 22 | UIButton-ANDYHighlighted: 3f5e9fb68fb3425bd9fddc030af452d3ac9d1613 23 | UIViewController-HYPContainer: 63d56dba6f2f334154304bd56892ba06ddb2005c 24 | 25 | COCOAPODS: 0.36.4 26 | -------------------------------------------------------------------------------- /Pod/Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Pod/Tests/Tests.m: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | @import XCTest; 3 | 4 | @interface Tests : XCTestCase 5 | 6 | @end 7 | 8 | @implementation Tests 9 | 10 | - (void)testPassingExample 11 | { 12 | NSArray *array; 13 | XCTAssertNil(array); 14 | } 15 | 16 | - (void)testFailingExample 17 | { 18 | NSArray *array; 19 | XCTAssertNotNil(array); 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Contract](https://raw.githubusercontent.com/hyperoslo/Contract/master/Images/cover-v2.png) 2 | 3 | Apps that require signatures in a contract, behold! 4 | 5 | No more crazyness, `Contract` makes signing your soul away much easier. 6 | 7 | ## Usage 8 | 9 | ```swift 10 | import UIKit 11 | 12 | @UIApplicationMain 13 | class AppDelegate: UIResponder, UIApplicationDelegate, HYPContractViewControllerDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application( 18 | application: UIApplication, 19 | didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 20 | window = UIWindow(frame: UIScreen.mainScreen().bounds) 21 | 22 | let contractController = HYPContractViewController( 23 | contractURL: "http://ga.berkeley.edu/wp-content/uploads/2015/02/pdf-sample.pdf", 24 | firstPartyName: "CEO", 25 | secondPartyName: "Michael Minion", 26 | needsSignature: true) 27 | 28 | contractController.delegate = self 29 | 30 | if let window = self.window { 31 | window.rootViewController = UINavigationController(rootViewController: contractController) 32 | window.makeKeyAndVisible() 33 | } 34 | 35 | return true 36 | } 37 | 38 | func contractControllerDidFinish( 39 | contractController: HYPContractViewController!, 40 | withFirstPartySignature firstPartySignature: UIImage!, 41 | andSecondPartySignature secondPartySignature: UIImage!) { 42 | println("finished") 43 | } 44 | 45 | func contractControllerDidDismiss(contractController: HYPContractViewController!) { 46 | println("dismiss") 47 | } 48 | } 49 | ``` 50 | 51 | ## How it looks 52 | 53 | ![Demo](https://raw.githubusercontent.com/hyperoslo/Contract/master/Images/demo.png) 54 | 55 | ## Installation 56 | 57 | **Contract** is available through [CocoaPods](http://cocoapods.org). To install 58 | it, simply add the following line to your Podfile: 59 | 60 | ```ruby 61 | pod 'Contract' 62 | ``` 63 | 64 | ## Author 65 | 66 | Hyper Interaktiv AS, ios@hyper.no 67 | 68 | ## License 69 | 70 | **Contract** is available under the MIT license. See the LICENSE file for more info. 71 | -------------------------------------------------------------------------------- /Source/HYPContractViewController.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @class HYPContract; 4 | 5 | static const CGSize HYPContractPopoverSize = { .width = 320.0f, .height = 360.0f }; 6 | 7 | @protocol HYPContractViewControllerDelegate; 8 | 9 | @interface HYPContractViewController : UIViewController 10 | 11 | @property (nonatomic, weak) id delegate; 12 | 13 | - (instancetype)initWithURLRequest:(NSURLRequest *)URLRequest 14 | firstPartyName:(NSString *)firstPartyName 15 | secondPartyName:(NSString *)secondPartyName 16 | needsSignature:(BOOL)needsSignature; 17 | 18 | - (void)toogleSignatureControl; 19 | 20 | @end 21 | 22 | @protocol HYPContractViewControllerDelegate 23 | 24 | - (void)contractControllerDidSign:(HYPContractViewController *)contractController 25 | firstPartySignature:(UIImage *)firstPartySignature 26 | andSecondPartySignature:(UIImage *)secondPartySignature; 27 | 28 | @optional 29 | - (void)contractController:(HYPContractViewController *)contractController 30 | didToogleSignatureControl:(BOOL)shown; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /Source/HYPContractViewController.m: -------------------------------------------------------------------------------- 1 | @import AssetsLibrary; 2 | 3 | #import "HYPContractViewController.h" 4 | 5 | #import "HYPSignaturesViewController.h" 6 | #import "HYPWebView.h" 7 | #import "SVProgressHUD.h" 8 | 9 | #import "UIViewController+HYPContainer.h" 10 | 11 | static CGFloat const HYPControlViewHeight = 210.0f; 12 | 13 | @interface HYPContractViewController () 14 | 15 | @property (nonatomic) BOOL controlViewPresented; 16 | @property (nonatomic) HYPWebView *webView; 17 | @property (nonatomic) HYPSignaturesViewController *controlsViewController; 18 | @property (nonatomic) CGRect previousRect; 19 | @property (nonatomic) UIImage *firstPartySignature; 20 | @property (nonatomic) UIImage *secondPartySignature; 21 | @property (nonatomic, copy) NSURLRequest *URLRequest; 22 | @property (nonatomic, copy) NSString *firstPartyName; 23 | @property (nonatomic, copy) NSString *secondPartyName; 24 | @property (nonatomic) BOOL needsSignature; 25 | 26 | @end 27 | 28 | @implementation HYPContractViewController 29 | 30 | - (instancetype)initWithURLRequest:(NSURLRequest *)URLRequest 31 | firstPartyName:(NSString *)firstPartyName 32 | secondPartyName:(NSString *)secondPartyName 33 | needsSignature:(BOOL)needsSignature { 34 | self = [super initWithNibName:nil bundle:nil]; 35 | if (!self) return nil; 36 | 37 | self.title = NSLocalizedString(@"Contract", nil); 38 | self.edgesForExtendedLayout = UIRectEdgeNone; 39 | 40 | _URLRequest = URLRequest; 41 | _firstPartyName = firstPartyName; 42 | _secondPartyName = secondPartyName; 43 | _needsSignature = needsSignature; 44 | 45 | return self; 46 | } 47 | 48 | #pragma mark - Getters 49 | 50 | - (HYPWebView *)webView { 51 | if (_webView) return _webView; 52 | 53 | _webView = [[HYPWebView alloc] initWithFrame:self.view.frame]; 54 | _webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 55 | 56 | return _webView; 57 | } 58 | 59 | - (HYPSignaturesViewController *)controlsViewController { 60 | if (_controlsViewController) return _controlsViewController; 61 | 62 | _controlsViewController = [[HYPSignaturesViewController alloc] initWithFirstPartyName:self.firstPartyName 63 | andSecondPartyName:self.secondPartyName]; 64 | _controlsViewController.view.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth; 65 | _controlsViewController.delegate = self; 66 | 67 | return _controlsViewController; 68 | } 69 | 70 | #pragma mark - View Life cycle 71 | 72 | - (void)viewDidLoad { 73 | [super viewDidLoad]; 74 | 75 | [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault]; 76 | 77 | [self.view addSubview:self.webView]; 78 | 79 | CGFloat y = CGRectGetHeight(self.view.frame); 80 | CGFloat width = CGRectGetWidth(self.view.frame); 81 | CGRect frame = CGRectMake(0.0f, y + HYPControlViewHeight, width, HYPControlViewHeight); 82 | [self hyp_addViewController:self.controlsViewController inFrame:frame]; 83 | 84 | self.controlViewPresented = NO; 85 | } 86 | 87 | - (void)viewDidAppear:(BOOL)animated { 88 | [super viewDidAppear:animated]; 89 | 90 | [self.webView loadRequest:self.URLRequest]; 91 | } 92 | 93 | - (void)viewWillDisappear:(BOOL)animated { 94 | [super viewWillDisappear:animated]; 95 | 96 | if (self.webView.isLoading) { 97 | [self.webView stopLoading]; 98 | } 99 | [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent]; 100 | } 101 | 102 | #pragma mark - Control Methods 103 | 104 | - (void)toogleSignatureControl { 105 | self.controlViewPresented = !self.controlViewPresented; 106 | 107 | [self animateControlView:self.controlsViewController.view 108 | show:self.controlViewPresented 109 | completion:^{ 110 | if ([self.delegate respondsToSelector:@selector(contractController:didToogleSignatureControl:)]) { 111 | [self.delegate contractController:self 112 | didToogleSignatureControl:self.controlViewPresented]; 113 | } 114 | }]; 115 | } 116 | 117 | - (void)animateControlView:(UIView *)view 118 | show:(BOOL)show 119 | completion:(void (^)())completion { 120 | CGRect webViewFrame = self.webView.frame; 121 | CGRect controlViewFrame = view.frame; 122 | 123 | CGFloat margin = CGRectGetHeight(self.view.frame); 124 | 125 | if (show) { 126 | margin -= HYPControlViewHeight; 127 | } else { 128 | margin += HYPControlViewHeight; 129 | } 130 | 131 | controlViewFrame.origin.y = margin; 132 | webViewFrame.size.height = margin; 133 | 134 | [UIView animateWithDuration:0.35f delay:0.0f 135 | options:UIViewAnimationOptionBeginFromCurrentState 136 | animations:^{ 137 | [self.webView setFrame:webViewFrame]; 138 | [view setFrame:controlViewFrame]; 139 | } completion:^(BOOL finished) { 140 | if (completion) { 141 | completion(); 142 | } 143 | }]; 144 | } 145 | 146 | #pragma mark - HYPSignaturesViewControllerDelegate 147 | 148 | - (void)signaturesViewController:(HYPSignaturesViewController *)signaturesViewController 149 | didFinishWithFirstPartySignature:(UIImage *)firstPartySignature 150 | secondPartySignature:(UIImage *)secondPartySignature { 151 | 152 | self.firstPartySignature = secondPartySignature; 153 | self.secondPartySignature = firstPartySignature; 154 | 155 | if ([self.delegate respondsToSelector:@selector(contractControllerDidSign:firstPartySignature:andSecondPartySignature:)]) { 156 | [self.delegate contractControllerDidSign:self 157 | firstPartySignature:self.firstPartySignature 158 | andSecondPartySignature:self.secondPartySignature]; 159 | } 160 | } 161 | 162 | @end 163 | -------------------------------------------------------------------------------- /Source/HYPSignatureViewController.h: -------------------------------------------------------------------------------- 1 | #import "HYPSignatureView.h" 2 | 3 | #import "UIButton+HYPSignatureViewController.h" 4 | 5 | static const CGFloat HYPSignatureHeight = 350.0f; 6 | static const CGFloat HYPSignatureWidth = 700.0f; 7 | static const CGFloat HYPButtonWidth = 200.0f; 8 | static const CGFloat HYPButtonHeight = 60.0f; 9 | static const CGFloat HYPNullifyButtonSignatureWidth = 300.0f; 10 | 11 | @class HYPEmployee; 12 | 13 | @protocol HYPSignatureViewControllerDelegate; 14 | 15 | @interface HYPSignatureViewController : UIViewController 16 | 17 | @property (nonatomic, weak) id delegate; 18 | @property (nonatomic) UIButton *doneButton; 19 | @property (nonatomic) UIButton *cancelButton; 20 | @property (nonatomic) UILabel *signHereLabel; 21 | @property (nonatomic) HYPSignatureView *signatureView; 22 | 23 | - (instancetype)initWithName:(NSString *)name; 24 | 25 | - (void)enableButtons:(BOOL)enabled; 26 | 27 | @end 28 | 29 | @protocol HYPSignatureViewControllerDelegate 30 | 31 | - (void)signatureViewControllerDidClear:(HYPSignatureViewController *)signatureViewController; 32 | 33 | - (void)signatureViewController:(HYPSignatureViewController *)signatureViewController 34 | didFinishWithSignature:(UIImage *)image; 35 | 36 | @end 37 | 38 | -------------------------------------------------------------------------------- /Source/HYPSignatureViewController.m: -------------------------------------------------------------------------------- 1 | #import "HYPSignatureViewController.h" 2 | 3 | #import "UIColor+Hex.h" 4 | 5 | static const CGFloat HYPSignatureSubjectY = 70.0f; 6 | 7 | @interface HYPSignatureViewController () 8 | 9 | @property (nonatomic) UILabel *signatureSubject; 10 | @property (nonatomic) UIView *lineSeparatorView; 11 | @property (nonatomic, copy) NSString *name; 12 | 13 | @end 14 | 15 | @implementation HYPSignatureViewController 16 | 17 | #pragma mark - Initialize 18 | 19 | - (instancetype)initWithName:(NSString *)name { 20 | self = [super init]; 21 | if (!self) return nil; 22 | 23 | _name = name; 24 | 25 | return self; 26 | } 27 | 28 | #pragma mark - Getters 29 | 30 | - (HYPSignatureView *)signatureView { 31 | if (_signatureView) return _signatureView; 32 | 33 | CGRect frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, HYPSignatureWidth, HYPSignatureHeight); 34 | _signatureView = [[HYPSignatureView alloc] initWithFrame:frame context:nil]; 35 | _signatureView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; 36 | _signatureView.userInteractionEnabled = NO; 37 | 38 | return _signatureView; 39 | } 40 | 41 | 42 | - (UILabel *)signHereLabel { 43 | if (_signHereLabel) return _signHereLabel; 44 | 45 | _signHereLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, HYPSignatureWidth, 350.0f)]; 46 | _signHereLabel.text = NSLocalizedString(@"TapHereToSign", nil); 47 | _signHereLabel.font = [UIFont fontWithName:@"DIN-Light" size:33.0]; 48 | _signHereLabel.textColor = [UIColor colorFromHex:@"455C73"]; 49 | _signHereLabel.textAlignment = NSTextAlignmentCenter; 50 | 51 | return _signHereLabel; 52 | } 53 | 54 | - (UIButton *)doneButton { 55 | if (_doneButton) return _doneButton; 56 | 57 | _doneButton = [UIButton whiteButtonWithFrame:CGRectMake(HYPSignatureWidth - HYPButtonWidth, 0.0f, HYPButtonWidth, HYPButtonHeight) 58 | title:NSLocalizedString(@"Ferdig", nil) 59 | target:self 60 | action:@selector(doneButtonPressed)]; 61 | _doneButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight; 62 | _doneButton.contentEdgeInsets = UIEdgeInsetsMake(0.0f, 0.0f, 0.0f, 33.0f); 63 | _doneButton.imageEdgeInsets = UIEdgeInsetsMake(-3.0f, 0.0f, 0.0f, 5.f); 64 | _doneButton.titleEdgeInsets = UIEdgeInsetsMake(0.0f, 0.0f, 0.0f, 0.0f); 65 | [_doneButton setImage:[UIImage imageNamed:@"Contract.bundle/check"] forState:UIControlStateNormal]; 66 | _doneButton.alpha = 0.0f; 67 | 68 | return _doneButton; 69 | } 70 | 71 | - (UIButton *)cancelButton { 72 | if (_cancelButton) return _cancelButton; 73 | 74 | NSString *title = [NSString stringWithFormat:@"%@ %@", NSLocalizedString(@"Clear", nil), NSLocalizedString(@"SignatureField", nil)]; 75 | _cancelButton = [UIButton whiteButtonWithFrame:CGRectMake(0.0f, 0.0f, HYPNullifyButtonSignatureWidth, HYPButtonHeight) 76 | title:title 77 | target:self 78 | action:@selector(cancelButtonPressed)]; 79 | _cancelButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; 80 | _cancelButton.contentEdgeInsets = UIEdgeInsetsMake(0.0f, 33.0f, 0.0f, 0.0f); 81 | _cancelButton.imageEdgeInsets = UIEdgeInsetsMake(-3.0f, -5.0f, 0.0f, 0.f); 82 | _cancelButton.titleEdgeInsets = UIEdgeInsetsMake(0.0f, 0.0f, 0.0f, 0.0f); 83 | [_cancelButton setImage:[UIImage imageNamed:@"Contract.bundle/clear"] forState:UIControlStateNormal]; 84 | _cancelButton.alpha = 0.0f; 85 | 86 | return _cancelButton; 87 | } 88 | 89 | - (UILabel *)signatureSubject { 90 | if (_signatureSubject) return _signatureSubject; 91 | 92 | _signatureSubject = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, HYPSignatureHeight - HYPSignatureSubjectY, HYPSignatureWidth, 30.0f)]; 93 | _signatureSubject.text = [NSString stringWithFormat:@"%@: %@", NSLocalizedString(@"Signature", nil), self.name]; 94 | _signatureSubject.font = [UIFont fontWithName:@"DIN-Regular" size:23.0]; 95 | _signatureSubject.textAlignment = NSTextAlignmentCenter; 96 | _signatureSubject.textColor = [UIColor colorFromHex:@"455C73"]; 97 | 98 | return _signatureSubject; 99 | } 100 | 101 | - (UIView *)lineSeparatorView { 102 | if (_lineSeparatorView) return _lineSeparatorView; 103 | 104 | CGFloat margin = 100.0f; 105 | _lineSeparatorView = [[UIView alloc] initWithFrame:CGRectMake(margin, HYPSignatureHeight - HYPSignatureSubjectY - 15.0f, HYPSignatureWidth - (2.0f * margin), 2.0f)]; 106 | _lineSeparatorView.backgroundColor = [UIColor colorFromHex:@"455C73"]; 107 | 108 | return _lineSeparatorView; 109 | } 110 | 111 | #pragma mark - View Life cycle 112 | 113 | - (void)viewDidLoad { 114 | [super viewDidLoad]; 115 | 116 | [self.view addSubview:self.signatureView]; 117 | [self.view addSubview:self.doneButton]; 118 | [self.view addSubview:self.cancelButton]; 119 | [self.view addSubview:self.signatureSubject]; 120 | [self.view addSubview:self.lineSeparatorView]; 121 | [self.view addSubview:self.signHereLabel]; 122 | 123 | self.view.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; 124 | self.view.layer.borderColor = [UIColor colorFromHex:@"3DAFEB"].CGColor; 125 | self.view.layer.cornerRadius = 10.0f; 126 | self.view.layer.borderWidth = 2.0f; 127 | self.view.layer.masksToBounds = YES; 128 | } 129 | 130 | #pragma mark - Actions 131 | 132 | - (void)cancelButtonPressed { 133 | [self.signatureView erase]; 134 | 135 | if ([self.delegate respondsToSelector:@selector(signatureViewControllerDidClear:)]) { 136 | [self.delegate signatureViewControllerDidClear:self]; 137 | } 138 | } 139 | 140 | - (void)doneButtonPressed { 141 | if ([self.delegate respondsToSelector:@selector(signatureViewController:didFinishWithSignature:)]) { 142 | [self.delegate signatureViewController:self didFinishWithSignature:[self.signatureView snapshot]]; 143 | } 144 | } 145 | 146 | - (void)enableButtons:(BOOL)enabled { 147 | self.cancelButton.enabled = enabled; 148 | self.doneButton.enabled = enabled; 149 | 150 | UIColor *color = (enabled) ? [UIColor colorFromHex:@"3DAFEB"] : [UIColor colorFromHex:@"F5F5F8"]; 151 | [self.cancelButton setTitleColor:color forState:UIControlStateNormal]; 152 | [self.doneButton setTitleColor:color forState:UIControlStateNormal]; 153 | 154 | UIImage *checkImage = (enabled) ? [UIImage imageNamed:@"Contract.bundle/check"] : [UIImage imageNamed:@"Contract.bundle/check_disabled"]; 155 | UIImage *clearImage = (enabled) ? [UIImage imageNamed:@"Contract.bundle/clear"] : [UIImage imageNamed:@"Contract.bundle/clear_disabled"]; 156 | [self.cancelButton setImage:clearImage forState:UIControlStateNormal]; 157 | [self.doneButton setImage:checkImage forState:UIControlStateNormal]; 158 | } 159 | 160 | 161 | @end 162 | -------------------------------------------------------------------------------- /Source/HYPSignaturesViewController.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @protocol HYPSignaturesViewControllerDelegate; 4 | 5 | @interface HYPSignaturesViewController : UIViewController 6 | 7 | @property (nonatomic, weak) id delegate; 8 | @property (nonatomic, readonly) UIImage *firstPartySignature; 9 | @property (nonatomic, readonly) UIImage *secondPartySignature; 10 | 11 | - (instancetype)initWithFirstPartyName:(NSString *)firsPartyName 12 | andSecondPartyName:(NSString *)secondPartyName; 13 | @end 14 | 15 | @protocol HYPSignaturesViewControllerDelegate 16 | 17 | - (void)signaturesViewController:(HYPSignaturesViewController *)signaturesViewController 18 | didFinishWithFirstPartySignature:(UIImage *)firstPartySignature 19 | secondPartySignature:(UIImage *)secondPartySignature; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Source/HYPSignaturesViewController.m: -------------------------------------------------------------------------------- 1 | #import "HYPSignaturesViewController.h" 2 | 3 | #import "HYPSignatureViewController.h" 4 | 5 | #import "UIViewController+HYPContainer.h" 6 | 7 | static const CGFloat HYPSignatureButtonX = 15.0f; 8 | static const CGFloat HYPSignatureButtonY = 15.0f; 9 | 10 | static const CGFloat HYPSignatureButtonHeight = 180.0f; 11 | static const CGFloat HYPSignatureButtonWidth = 360.0f; 12 | 13 | @interface HYPSignaturesViewController () 14 | 15 | @property (nonatomic, copy) NSString *firstPartyName; 16 | @property (nonatomic, copy) NSString *secondPartyName; 17 | 18 | @property (nonatomic) HYPSignatureViewController *firstPartySignatureViewController; 19 | @property (nonatomic) HYPSignatureViewController *secondPartySignatureViewController; 20 | @property (nonatomic) UIView *overlayView; 21 | 22 | @property (nonatomic) CGRect originalRect; 23 | @property (nonatomic) CGRect previousRect; 24 | 25 | @property (nonatomic) UITapGestureRecognizer *firstPartyTapRecognizer; 26 | @property (nonatomic) UITapGestureRecognizer *secondPartyTapRecognizer; 27 | 28 | @property (nonatomic) UIImage *firstPartySignature; 29 | @property (nonatomic) UIImage *secondPartySignature; 30 | 31 | @end 32 | 33 | @implementation HYPSignaturesViewController 34 | 35 | #pragma mark - Initalization 36 | 37 | - (instancetype)initWithFirstPartyName:(NSString *)firsPartyName 38 | andSecondPartyName:(NSString *)secondPartyName { 39 | self = [super init]; 40 | if (!self) return nil; 41 | 42 | _firstPartyName = firsPartyName; 43 | _secondPartyName = secondPartyName; 44 | 45 | return self; 46 | } 47 | 48 | #pragma mark - Getters 49 | 50 | - (HYPSignatureViewController *)firstPartySignatureViewController { 51 | if (_firstPartySignatureViewController) return _firstPartySignatureViewController; 52 | 53 | _firstPartySignatureViewController = [[HYPSignatureViewController alloc] initWithName:self.firstPartyName]; 54 | _firstPartySignatureViewController.delegate = self; 55 | 56 | return _firstPartySignatureViewController; 57 | } 58 | 59 | - (HYPSignatureViewController *)secondPartySignatureViewController { 60 | if (_secondPartySignatureViewController) return _secondPartySignatureViewController; 61 | 62 | _secondPartySignatureViewController = [[HYPSignatureViewController alloc] initWithName:self.secondPartyName]; 63 | _secondPartySignatureViewController.delegate = self; 64 | 65 | return _secondPartySignatureViewController; 66 | } 67 | 68 | 69 | - (UIView *)overlayView { 70 | if (_overlayView) return _overlayView; 71 | 72 | _overlayView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 73 | _overlayView.backgroundColor = [UIColor colorWithWhite:0.0f alpha:0.5f]; 74 | _overlayView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 75 | _overlayView.alpha = 0.0f; 76 | 77 | return _overlayView; 78 | } 79 | 80 | #pragma mark - View Life cycle 81 | 82 | - (void)viewDidLoad { 83 | [super viewDidLoad]; 84 | 85 | CGRect frame = CGRectMake(HYPSignatureButtonX, HYPSignatureButtonY, HYPSignatureButtonWidth, HYPSignatureButtonHeight); 86 | [self hyp_addViewController:self.firstPartySignatureViewController]; 87 | self.firstPartySignatureViewController.view.layer.transform = CATransform3DMakeScale(.515, .515, 1); 88 | self.firstPartySignatureViewController.view.frame = frame; 89 | self.firstPartySignatureViewController.view.autoresizingMask = UIViewAutoresizingFlexibleRightMargin; 90 | 91 | self.firstPartyTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(employerSignatureTapped)]; 92 | [self.firstPartySignatureViewController.view addGestureRecognizer:self.firstPartyTapRecognizer]; 93 | 94 | frame.origin.x = CGRectGetWidth([[UIScreen mainScreen] bounds]) - HYPSignatureButtonWidth - HYPSignatureButtonX; 95 | [self hyp_addViewController:self.secondPartySignatureViewController]; 96 | self.secondPartySignatureViewController.view.layer.transform = CATransform3DMakeScale(.515, .515, 1); 97 | self.secondPartySignatureViewController.view.frame = frame; 98 | self.secondPartySignatureViewController.view.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; 99 | 100 | self.secondPartyTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(employeeSignatureTapped)]; 101 | [self.secondPartySignatureViewController.view addGestureRecognizer:self.secondPartyTapRecognizer]; 102 | } 103 | 104 | #pragma mark - Actions 105 | 106 | - (void)employerSignatureTapped { 107 | [self expandSignature:self.firstPartySignatureViewController]; 108 | } 109 | 110 | - (void)employeeSignatureTapped { 111 | [self expandSignature:self.secondPartySignatureViewController]; 112 | } 113 | 114 | - (void)expandSignature:(HYPSignatureViewController *)signatureViewController { 115 | [self setUpGestureInSignatureController:signatureViewController removed:YES]; 116 | 117 | self.overlayView.frame = self.navigationController.view.bounds; 118 | [self.navigationController.view addSubview:self.overlayView]; 119 | 120 | self.originalRect = signatureViewController.view.frame; 121 | CGRect newRect = [self.view convertRect:signatureViewController.view.frame toView:self.navigationController.view]; 122 | [self.navigationController hyp_addViewController:signatureViewController]; 123 | 124 | signatureViewController.view.frame = newRect; 125 | self.previousRect = newRect; 126 | 127 | CGRect mainBounds = [[UIScreen mainScreen] bounds]; 128 | 129 | CGRect frame = CGRectMake((CGRectGetWidth(mainBounds) / 2) - HYPSignatureWidth / 2, (CGRectGetHeight(mainBounds) / 2) - HYPSignatureHeight / 2, HYPSignatureWidth, HYPSignatureHeight); 130 | 131 | [UIView animateWithDuration:0.4 delay:0.0f options:UIViewAnimationOptionAllowUserInteraction animations:^{ 132 | signatureViewController.view.layer.transform = CATransform3DIdentity; 133 | signatureViewController.view.frame = frame; 134 | self.overlayView.alpha = 1.0f; 135 | signatureViewController.signHereLabel.alpha = 0.0f; 136 | signatureViewController.doneButton.alpha = 1.0f; 137 | signatureViewController.cancelButton.alpha = 1.0f; 138 | } completion:^(BOOL finished) { 139 | signatureViewController.signatureView.userInteractionEnabled = YES; 140 | }]; 141 | } 142 | 143 | - (void)dismissSignatureController:(HYPSignatureViewController *)signatureViewController { 144 | CGRect frame = self.previousRect; 145 | 146 | [UIView animateWithDuration:0.4 animations:^{ 147 | signatureViewController.view.layer.transform = CATransform3DMakeScale(.515, .515, 1); 148 | signatureViewController.view.frame = frame; 149 | self.overlayView.alpha = 0.0f; 150 | signatureViewController.doneButton.alpha = 0.0f; 151 | signatureViewController.cancelButton.alpha = 0.0f; 152 | // ONLY SHOW IF NOT SIGNED-signatureViewController.signHereLabel.alpha = 1.0f; 153 | } completion:^(BOOL finished) { 154 | [self hyp_addViewController:signatureViewController]; 155 | [self.overlayView removeFromSuperview]; 156 | signatureViewController.view.frame = self.originalRect; 157 | signatureViewController.signatureView.userInteractionEnabled = NO; 158 | [self setUpGestureInSignatureController:signatureViewController removed:NO]; 159 | }]; 160 | } 161 | 162 | - (void)setUpGestureInSignatureController:(HYPSignatureViewController *)signatureViewController removed:(BOOL)removed { 163 | UIGestureRecognizer *gestureRecognizer; 164 | 165 | BOOL isEmployeeSignature = ([signatureViewController isEqual:self.secondPartySignatureViewController]); 166 | if (isEmployeeSignature) { 167 | gestureRecognizer = self.secondPartyTapRecognizer; 168 | } else { 169 | gestureRecognizer = self.firstPartyTapRecognizer; 170 | } 171 | 172 | if (removed) { 173 | [signatureViewController.view removeGestureRecognizer:gestureRecognizer]; 174 | } else { 175 | [signatureViewController.view addGestureRecognizer:gestureRecognizer]; 176 | } 177 | 178 | if (removed) { 179 | signatureViewController.view.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin; 180 | } else { 181 | signatureViewController.view.autoresizingMask = (isEmployeeSignature)? UIViewAutoresizingFlexibleLeftMargin : UIViewAutoresizingFlexibleRightMargin; 182 | } 183 | } 184 | 185 | #pragma mark - HYPSignatureViewControllerDelegate 186 | 187 | - (void)signatureViewControllerDidClear:(HYPSignatureViewController *)signatureViewController { 188 | BOOL isFirstParty = ([signatureViewController isEqual:self.firstPartySignatureViewController]); 189 | 190 | if (isFirstParty) { 191 | self.firstPartySignature = nil; 192 | } else { 193 | self.secondPartySignature = nil; 194 | } 195 | 196 | [self dismissSignatureController:signatureViewController]; 197 | 198 | if ([self.delegate respondsToSelector:@selector(signaturesViewController:didFinishWithFirstPartySignature:secondPartySignature:)]) { 199 | [self.delegate signaturesViewController:self 200 | didFinishWithFirstPartySignature:self.firstPartySignature 201 | secondPartySignature:self.secondPartySignature]; 202 | } 203 | } 204 | 205 | - (void)signatureViewController:(HYPSignatureViewController *)signatureViewController 206 | didFinishWithSignature:(UIImage *)image { 207 | BOOL isFirstParty = ([signatureViewController isEqual:self.firstPartySignatureViewController]); 208 | 209 | if (isFirstParty) { 210 | self.firstPartySignature = image; 211 | } else { 212 | self.secondPartySignature = image; 213 | } 214 | 215 | [self dismissSignatureController:signatureViewController]; 216 | 217 | if ([self.delegate respondsToSelector:@selector(signaturesViewController:didFinishWithFirstPartySignature:secondPartySignature:)]) { 218 | [self.delegate signaturesViewController:self 219 | didFinishWithFirstPartySignature:self.firstPartySignature 220 | secondPartySignature:self.secondPartySignature]; 221 | } 222 | } 223 | 224 | @end 225 | -------------------------------------------------------------------------------- /Source/UIButton+HYPSignatureViewController.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @interface UIButton (HYPSignatureViewController) 4 | 5 | + (UIButton *)whiteButtonWithFrame:(CGRect)frame 6 | title:(NSString *)title 7 | target:(id)target 8 | action:(SEL)action; 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /Source/UIButton+HYPSignatureViewController.m: -------------------------------------------------------------------------------- 1 | #import "UIButton+HYPSignatureViewController.h" 2 | 3 | #import "UIColor+Hex.h" 4 | #import "UIButton+ANDYHighlighted.h" 5 | 6 | @implementation UIButton (HYPSignatureViewController) 7 | 8 | + (UIButton *)whiteButtonWithFrame:(CGRect)frame 9 | title:(NSString *)title 10 | target:(id)target 11 | action:(SEL)action { 12 | UIButton *button = [[UIButton alloc] initWithFrame:frame]; 13 | button.layer.cornerRadius = 0.0f; 14 | button.backgroundColor = [UIColor clearColor]; 15 | 16 | button.contentEdgeInsets = UIEdgeInsetsMake(0.0f, 24.0f, 0.0f, 33.0f); 17 | button.imageEdgeInsets = UIEdgeInsetsMake(-2.0f, -7.0f, 0.0f, 33.0f); 18 | button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; 19 | button.titleLabel.font = [UIFont fontWithName:@"Avenir-Medium" size:17.0]; 20 | 21 | button.highlightedBackgroundColor = [UIColor clearColor]; 22 | button.layer.borderColor = [UIColor colorFromHex:@"3DAFEB"].CGColor; 23 | 24 | [button setTitleColor:[UIColor colorFromHex:@"455C73"] forState:UIControlStateNormal]; 25 | [button setTitleColor:[UIColor colorFromHex:@"28649C"] forState:UIControlStateHighlighted]; 26 | [button setTitle:title forState:UIControlStateNormal]; 27 | 28 | if (target && action) { 29 | button.titleColor = [UIColor colorFromHex:@"3DAFEB"]; 30 | button.highlightedTitleColor = [UIColor colorFromHex:@"28649C"]; 31 | [button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside]; 32 | [button setTitleColor:[UIColor colorFromHex:@"3DAFEB"] forState:UIControlStateNormal]; 33 | } else { 34 | button.userInteractionEnabled = NO; 35 | } 36 | 37 | return button; 38 | } 39 | 40 | @end 41 | --------------------------------------------------------------------------------