├── .gitignore ├── .travis.yml ├── LICENSE ├── Podfile ├── Podfile.lock ├── README.md ├── VENCalculatorInputView.podspec ├── VENCalculatorInputView.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ └── VENCalculatorInputView.xcscheme ├── VENCalculatorInputView.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── WorkspaceSettings.xcsettings ├── VENCalculatorInputView ├── Images │ ├── VENCalculatorIconBackspace.png │ ├── VENCalculatorIconBackspace@2x.png │ └── VENCalculatorIconBackspace@3x.png ├── NSString+VENCalculatorInputView.h ├── NSString+VENCalculatorInputView.m ├── UITextField+VENCalculatorInputView.h ├── UITextField+VENCalculatorInputView.m ├── VENCalculatorInputTextField.h ├── VENCalculatorInputTextField.m ├── VENCalculatorInputView-Prefix.pch ├── VENCalculatorInputView.h ├── VENCalculatorInputView.m ├── VENCalculatorInputView.xib ├── VENMoneyCalculator.h └── VENMoneyCalculator.m ├── VENCalculatorInputViewSample ├── Podfile ├── Podfile.lock ├── VENCalculatorInputViewSample.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata ├── VENCalculatorInputViewSample.xcworkspace │ └── contents.xcworkspacedata ├── VENCalculatorInputViewSample │ ├── Base.lproj │ │ └── Main.storyboard │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── VENAppDelegate.h │ ├── VENAppDelegate.m │ ├── VENCalculatorInputViewSample-Info.plist │ ├── VENCalculatorInputViewSample-Prefix.pch │ ├── VENViewController.h │ ├── VENViewController.m │ ├── en.lproj │ │ └── InfoPlist.strings │ └── main.m └── VENCalculatorInputViewSampleTests │ ├── VENCalculatorInputViewSampleTests-Info.plist │ ├── VENCalculatorInputViewSampleTests.m │ ├── VENCalculatorSpecs.m │ └── en.lproj │ └── InfoPlist.strings └── VENCalculatorInputViewTests ├── NSString+VENCalculatorInputViewSpec.m ├── UITextField+VENCalculatorInputViewSpec.m ├── VENCalculatorInputViewTests-Info.plist ├── VENMoneyCalculatorSpec.m └── en.lproj └── InfoPlist.strings /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # CocoaPods 23 | Pods -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | before_install: 3 | - gem i cocoapods --no-ri --no-rdoc 4 | - brew uninstall xctool; brew install xctool --HEAD; 5 | xcode_workspace: VENCalculatorInputView.xcworkspace 6 | xcode_scheme: VENCalculatorInputView 7 | xcode_sdk: iphonesimulator 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Ayaka Nonaka 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '7.0' 2 | 3 | target 'VENCalculatorInputViewTests', :exclusive => true do 4 | pod 'Specta', '~> 0.2.1' 5 | pod 'Expecta', '~> 0.2.2' 6 | pod 'OCMock', '~>3.0.0' 7 | end 8 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Expecta (0.2.4) 3 | - OCMock (3.0.2) 4 | - Specta (0.2.1) 5 | 6 | DEPENDENCIES: 7 | - Expecta (~> 0.2.2) 8 | - OCMock (~> 3.0.0) 9 | - Specta (~> 0.2.1) 10 | 11 | SPEC CHECKSUMS: 12 | Expecta: cfaf1d3e2e194ca704a25e997093d30a1ce70b61 13 | OCMock: 1f0871af0f397183f33e7552cca088bd2b485c25 14 | Specta: 15a276a6343867b426d5ed135d5aa4d04123a573 15 | 16 | COCOAPODS: 0.37.2 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | VENCalculatorInputView 2 | ========= 3 | 4 | [![Build Status](https://travis-ci.org/venmo/VENCalculatorInputView.svg?branch=master)](https://travis-ci.org/venmo/VENCalculatorInputView) 5 | 6 | VENCalculatorInputView is the calculator keyboard that is used in the [Venmo](https://venmo.com/) iOS app. 7 | Available for iOS 6 and beyond. Enjoy. 8 | 9 | ![alt text](http://i.imgur.com/VWgymjH.gif "VENCalculatorInputView demo") 10 | 11 | Installation 12 | ---- 13 | 14 | The easiest way to get started is to use [CocoaPods](http://cocoapods.org/). Just add the following line to your Podfile: 15 | 16 | ```ruby 17 | pod 'VENCalculatorInputView', '~> 1.5' 18 | ``` 19 | 20 | Sample Usage 21 | ---- 22 | You can choose to use just ```VENCalculatorInputView``` (only the keyboard) and define your own behavior or use ```VENCalculatorInputTextField``` (keyboard + text field with money calculation built in). 23 | 24 | ### Using just the calculator keyboard 25 | 26 | #### 1. Set the input view. 27 | Find the ```UITextField``` or ```UITextView``` that you want to display the keyboard and set its ```inputView``` to an instance of ```VENCalculatorInputView```. 28 | 29 | ```obj-c 30 | myTextField.inputView = [VENCalculatorInputView new]; 31 | ``` 32 | 33 | This will have ```VENCalculatorInputView``` display when ```myTextField``` becomes ```firstResponder``` instead of the system keyboard. 34 | 35 | #### 2. Implement the `````` methods. 36 | 37 | First, have a class implement the `````` protocol and set ```myTextField.inputView.delegate``` to an instance of that class. 38 | 39 | Next, implement the delegate method that handles keyboard input: 40 | 41 | ```obj-c 42 | - (void)calculatorInputView:(VENCalculatorInputView *)inputView didTapKey:(NSString *)key { 43 | NSLog(@"Just tapped key: %@", key); 44 | // Handle the input. Something like [myTextField insertText:key]; 45 | } 46 | ``` 47 | 48 | Finally, implement the delegate method that handles the backspace key: 49 | 50 | ```obj-c 51 | - (void)calculatorInputViewDidTapBackspace:(VENCalculatorInputView *)calculatorInputView { 52 | NSLog(@"Just tapped backspace."); 53 | // Handle the backspace. Something like [myTextField deleteBackward]; 54 | } 55 | ``` 56 | 57 | Try it! 58 | 59 | You can read more about custom keyboards in [Apple’s documentation](https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/InputViews/InputViews.html). 60 | 61 | ### Using the calculator text field (optimized for money calculation) 62 | 63 | All you need to do is use ```VENCalculatorInputTextField``` instead of ```UITextField``` and use it like normal text field. It will automagically handle the input and make calculations. Take a look at out our ```VENCalculatorInputViewSample``` project. 64 | 65 | Localization 66 | ------ 67 | 68 | Different regions use different symbols as their decimal separator (e.g. ```.```, ```,```). By default, ```VENCalculatorInputView``` and ```VENCalculatorInputTextField``` use the current locale of the device. You can change it by setting the ```locale``` property. 69 | 70 | Testing 71 | ------ 72 | 73 | We’ve written some tests. You can run them by opening the project in Xcode and hitting `Command-U`. 74 | 75 | Contributing 76 | ------------ 77 | 78 | We’d love to see your ideas for improving this library! The best way to contribute is by submitting a pull request. We’ll do our best to respond to your patch as soon as possible. You can also submit a [new GitHub issue](https://github.com/venmo/VENCalculatorInputView/issues/new) if you find bugs or have questions. :octocat: 79 | 80 | Please make sure to follow our general coding style and add test coverage for new features! 81 | -------------------------------------------------------------------------------- /VENCalculatorInputView.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "VENCalculatorInputView" 3 | s.version = "1.5.4" 4 | s.summary = "Venmo-style calculator keyboard for iOS" 5 | s.description = <<-DESC 6 | A pretty calculator keyboard for iOS. Use it as a standalone keyboard or use our VENCalculatorInputTextField. 7 | DESC 8 | 9 | s.homepage = "https://github.com/venmo/VENCalculatorInputView" 10 | s.license = { :type => 'MIT', :file => 'LICENSE' } 11 | s.author = { "Ayaka Nonaka" => "ayaka@venmo.com" } 12 | s.platform = :ios, '6.0' 13 | s.ios.deployment_target = '6.0' 14 | s.source = { :git => "https://github.com/venmo/VENCalculatorInputView.git", 15 | :tag => "v#{s.version}" 16 | } 17 | s.source_files = 'VENCalculatorInputView/**/*.{h,m}' 18 | s.resources = ["VENCalculatorInputView/**/*.{xib,png}"] 19 | s.requires_arc = true 20 | end 21 | -------------------------------------------------------------------------------- /VENCalculatorInputView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1AA4581B1B33ED8400708FFE /* VENCalculatorIconBackspace@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1AA4581A1B33ED8400708FFE /* VENCalculatorIconBackspace@3x.png */; }; 11 | 2F74D09D196F533B0040C816 /* UITextField+VENCalculatorInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F74D09C196F533B0040C816 /* UITextField+VENCalculatorInputView.m */; }; 12 | 2F74D09F196F53E20040C816 /* UITextField+VENCalculatorInputViewSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F74D09E196F53E20040C816 /* UITextField+VENCalculatorInputViewSpec.m */; }; 13 | 40BED60EE864401D8AFB2433 /* libPods-VENCalculatorInputViewTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 142758DF9FEC443BA2D635DE /* libPods-VENCalculatorInputViewTests.a */; }; 14 | B6F22CFD18AC031100543816 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6F22CFC18AC031100543816 /* Foundation.framework */; }; 15 | B6F22D0C18AC031100543816 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6F22CFC18AC031100543816 /* Foundation.framework */; }; 16 | B6F22D1118AC031100543816 /* libVENCalculatorInputView.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B6F22CF918AC031100543816 /* libVENCalculatorInputView.a */; }; 17 | B6F22D1718AC031100543816 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = B6F22D1518AC031100543816 /* InfoPlist.strings */; }; 18 | B6F22D2318AC039100543816 /* VENMoneyCalculatorSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = B6F22D2218AC039100543816 /* VENMoneyCalculatorSpec.m */; }; 19 | B6F22D2E18AC039F00543816 /* VENMoneyCalculator.m in Sources */ = {isa = PBXBuildFile; fileRef = B6F22D2518AC039F00543816 /* VENMoneyCalculator.m */; }; 20 | B6F22D2F18AC039F00543816 /* VENCalculatorInputTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = B6F22D2918AC039F00543816 /* VENCalculatorInputTextField.m */; }; 21 | B6F22D3018AC039F00543816 /* VENCalculatorInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = B6F22D2C18AC039F00543816 /* VENCalculatorInputView.m */; }; 22 | B6F22D3418AC03C700543816 /* VENCalculatorIconBackspace.png in Resources */ = {isa = PBXBuildFile; fileRef = B6F22D3218AC03C700543816 /* VENCalculatorIconBackspace.png */; }; 23 | B6F22D3518AC03C700543816 /* VENCalculatorIconBackspace@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B6F22D3318AC03C700543816 /* VENCalculatorIconBackspace@2x.png */; }; 24 | B6F22D3718AC045300543816 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6F22D3618AC045300543816 /* CoreGraphics.framework */; }; 25 | B6FD6362196BAB8700D1913C /* NSString+VENCalculatorInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = B6FD6361196BAB8700D1913C /* NSString+VENCalculatorInputView.m */; }; 26 | B6FD6364196BB09D00D1913C /* NSString+VENCalculatorInputViewSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = B6FD6363196BB09D00D1913C /* NSString+VENCalculatorInputViewSpec.m */; }; 27 | /* End PBXBuildFile section */ 28 | 29 | /* Begin PBXContainerItemProxy section */ 30 | B6F22D0F18AC031100543816 /* PBXContainerItemProxy */ = { 31 | isa = PBXContainerItemProxy; 32 | containerPortal = B6F22CF118AC031000543816 /* Project object */; 33 | proxyType = 1; 34 | remoteGlobalIDString = B6F22CF818AC031000543816; 35 | remoteInfo = VENCalculatorInputView; 36 | }; 37 | /* End PBXContainerItemProxy section */ 38 | 39 | /* Begin PBXCopyFilesBuildPhase section */ 40 | B6F22CF718AC031000543816 /* CopyFiles */ = { 41 | isa = PBXCopyFilesBuildPhase; 42 | buildActionMask = 2147483647; 43 | dstPath = "include/$(PRODUCT_NAME)"; 44 | dstSubfolderSpec = 16; 45 | files = ( 46 | ); 47 | runOnlyForDeploymentPostprocessing = 0; 48 | }; 49 | /* End PBXCopyFilesBuildPhase section */ 50 | 51 | /* Begin PBXFileReference section */ 52 | 142758DF9FEC443BA2D635DE /* libPods-VENCalculatorInputViewTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-VENCalculatorInputViewTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | 1AA4581A1B33ED8400708FFE /* VENCalculatorIconBackspace@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "VENCalculatorIconBackspace@3x.png"; sourceTree = ""; }; 54 | 2F74D09B196F533B0040C816 /* UITextField+VENCalculatorInputView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITextField+VENCalculatorInputView.h"; sourceTree = ""; }; 55 | 2F74D09C196F533B0040C816 /* UITextField+VENCalculatorInputView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITextField+VENCalculatorInputView.m"; sourceTree = ""; }; 56 | 2F74D09E196F53E20040C816 /* UITextField+VENCalculatorInputViewSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITextField+VENCalculatorInputViewSpec.m"; sourceTree = ""; }; 57 | 382246DCE4C0E18FFC29538F /* Pods-VENCalculatorInputViewTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VENCalculatorInputViewTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-VENCalculatorInputViewTests/Pods-VENCalculatorInputViewTests.debug.xcconfig"; sourceTree = ""; }; 58 | B6F22CF918AC031100543816 /* libVENCalculatorInputView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libVENCalculatorInputView.a; sourceTree = BUILT_PRODUCTS_DIR; }; 59 | B6F22CFC18AC031100543816 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 60 | B6F22D0018AC031100543816 /* VENCalculatorInputView-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "VENCalculatorInputView-Prefix.pch"; sourceTree = ""; }; 61 | B6F22D0918AC031100543816 /* VENCalculatorInputViewTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = VENCalculatorInputViewTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 62 | B6F22D1418AC031100543816 /* VENCalculatorInputViewTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "VENCalculatorInputViewTests-Info.plist"; sourceTree = ""; }; 63 | B6F22D1618AC031100543816 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 64 | B6F22D2218AC039100543816 /* VENMoneyCalculatorSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VENMoneyCalculatorSpec.m; sourceTree = ""; }; 65 | B6F22D2418AC039F00543816 /* VENMoneyCalculator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VENMoneyCalculator.h; sourceTree = ""; }; 66 | B6F22D2518AC039F00543816 /* VENMoneyCalculator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VENMoneyCalculator.m; sourceTree = ""; }; 67 | B6F22D2818AC039F00543816 /* VENCalculatorInputTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VENCalculatorInputTextField.h; sourceTree = ""; }; 68 | B6F22D2918AC039F00543816 /* VENCalculatorInputTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VENCalculatorInputTextField.m; sourceTree = ""; }; 69 | B6F22D2A18AC039F00543816 /* VENCalculatorInputView-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "VENCalculatorInputView-Prefix.pch"; sourceTree = ""; }; 70 | B6F22D2B18AC039F00543816 /* VENCalculatorInputView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VENCalculatorInputView.h; sourceTree = ""; }; 71 | B6F22D2C18AC039F00543816 /* VENCalculatorInputView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VENCalculatorInputView.m; sourceTree = ""; }; 72 | B6F22D2D18AC039F00543816 /* VENCalculatorInputView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = VENCalculatorInputView.xib; sourceTree = ""; }; 73 | B6F22D3218AC03C700543816 /* VENCalculatorIconBackspace.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = VENCalculatorIconBackspace.png; sourceTree = ""; }; 74 | B6F22D3318AC03C700543816 /* VENCalculatorIconBackspace@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "VENCalculatorIconBackspace@2x.png"; sourceTree = ""; }; 75 | B6F22D3618AC045300543816 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 76 | B6FD6360196BAB8700D1913C /* NSString+VENCalculatorInputView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+VENCalculatorInputView.h"; sourceTree = ""; }; 77 | B6FD6361196BAB8700D1913C /* NSString+VENCalculatorInputView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+VENCalculatorInputView.m"; sourceTree = ""; }; 78 | B6FD6363196BB09D00D1913C /* NSString+VENCalculatorInputViewSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+VENCalculatorInputViewSpec.m"; sourceTree = ""; }; 79 | BA38E94872D6B1E128555B04 /* Pods-VENCalculatorInputViewTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VENCalculatorInputViewTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-VENCalculatorInputViewTests/Pods-VENCalculatorInputViewTests.release.xcconfig"; sourceTree = ""; }; 80 | /* End PBXFileReference section */ 81 | 82 | /* Begin PBXFrameworksBuildPhase section */ 83 | B6F22CF618AC031000543816 /* Frameworks */ = { 84 | isa = PBXFrameworksBuildPhase; 85 | buildActionMask = 2147483647; 86 | files = ( 87 | B6F22D3718AC045300543816 /* CoreGraphics.framework in Frameworks */, 88 | B6F22CFD18AC031100543816 /* Foundation.framework in Frameworks */, 89 | ); 90 | runOnlyForDeploymentPostprocessing = 0; 91 | }; 92 | B6F22D0618AC031100543816 /* Frameworks */ = { 93 | isa = PBXFrameworksBuildPhase; 94 | buildActionMask = 2147483647; 95 | files = ( 96 | B6F22D0C18AC031100543816 /* Foundation.framework in Frameworks */, 97 | B6F22D1118AC031100543816 /* libVENCalculatorInputView.a in Frameworks */, 98 | 40BED60EE864401D8AFB2433 /* libPods-VENCalculatorInputViewTests.a in Frameworks */, 99 | ); 100 | runOnlyForDeploymentPostprocessing = 0; 101 | }; 102 | /* End PBXFrameworksBuildPhase section */ 103 | 104 | /* Begin PBXGroup section */ 105 | 188C84F12C216EDAE3E7DA39 /* Pods */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 382246DCE4C0E18FFC29538F /* Pods-VENCalculatorInputViewTests.debug.xcconfig */, 109 | BA38E94872D6B1E128555B04 /* Pods-VENCalculatorInputViewTests.release.xcconfig */, 110 | ); 111 | name = Pods; 112 | sourceTree = ""; 113 | }; 114 | B6F22CF018AC031000543816 = { 115 | isa = PBXGroup; 116 | children = ( 117 | B6F22CFE18AC031100543816 /* VENCalculatorInputView */, 118 | B6F22D1218AC031100543816 /* VENCalculatorInputViewTests */, 119 | B6F22CFB18AC031100543816 /* Frameworks */, 120 | B6F22CFA18AC031100543816 /* Products */, 121 | 188C84F12C216EDAE3E7DA39 /* Pods */, 122 | ); 123 | sourceTree = ""; 124 | }; 125 | B6F22CFA18AC031100543816 /* Products */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | B6F22CF918AC031100543816 /* libVENCalculatorInputView.a */, 129 | B6F22D0918AC031100543816 /* VENCalculatorInputViewTests.xctest */, 130 | ); 131 | name = Products; 132 | sourceTree = ""; 133 | }; 134 | B6F22CFB18AC031100543816 /* Frameworks */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | B6F22D3618AC045300543816 /* CoreGraphics.framework */, 138 | B6F22CFC18AC031100543816 /* Foundation.framework */, 139 | 142758DF9FEC443BA2D635DE /* libPods-VENCalculatorInputViewTests.a */, 140 | ); 141 | name = Frameworks; 142 | sourceTree = ""; 143 | }; 144 | B6F22CFE18AC031100543816 /* VENCalculatorInputView */ = { 145 | isa = PBXGroup; 146 | children = ( 147 | B6F22D2418AC039F00543816 /* VENMoneyCalculator.h */, 148 | B6F22D2518AC039F00543816 /* VENMoneyCalculator.m */, 149 | B6F22D2818AC039F00543816 /* VENCalculatorInputTextField.h */, 150 | B6F22D2918AC039F00543816 /* VENCalculatorInputTextField.m */, 151 | B6F22D2A18AC039F00543816 /* VENCalculatorInputView-Prefix.pch */, 152 | B6F22D2B18AC039F00543816 /* VENCalculatorInputView.h */, 153 | B6F22D2C18AC039F00543816 /* VENCalculatorInputView.m */, 154 | B6F22D2D18AC039F00543816 /* VENCalculatorInputView.xib */, 155 | 2F74D09B196F533B0040C816 /* UITextField+VENCalculatorInputView.h */, 156 | 2F74D09C196F533B0040C816 /* UITextField+VENCalculatorInputView.m */, 157 | B6FD6360196BAB8700D1913C /* NSString+VENCalculatorInputView.h */, 158 | B6FD6361196BAB8700D1913C /* NSString+VENCalculatorInputView.m */, 159 | B6F22D3118AC03C700543816 /* Images */, 160 | B6F22CFF18AC031100543816 /* Supporting Files */, 161 | ); 162 | path = VENCalculatorInputView; 163 | sourceTree = ""; 164 | }; 165 | B6F22CFF18AC031100543816 /* Supporting Files */ = { 166 | isa = PBXGroup; 167 | children = ( 168 | B6F22D0018AC031100543816 /* VENCalculatorInputView-Prefix.pch */, 169 | ); 170 | name = "Supporting Files"; 171 | sourceTree = ""; 172 | }; 173 | B6F22D1218AC031100543816 /* VENCalculatorInputViewTests */ = { 174 | isa = PBXGroup; 175 | children = ( 176 | 2F74D09E196F53E20040C816 /* UITextField+VENCalculatorInputViewSpec.m */, 177 | B6F22D2218AC039100543816 /* VENMoneyCalculatorSpec.m */, 178 | B6FD6363196BB09D00D1913C /* NSString+VENCalculatorInputViewSpec.m */, 179 | B6F22D1318AC031100543816 /* Supporting Files */, 180 | ); 181 | path = VENCalculatorInputViewTests; 182 | sourceTree = ""; 183 | }; 184 | B6F22D1318AC031100543816 /* Supporting Files */ = { 185 | isa = PBXGroup; 186 | children = ( 187 | B6F22D1418AC031100543816 /* VENCalculatorInputViewTests-Info.plist */, 188 | B6F22D1518AC031100543816 /* InfoPlist.strings */, 189 | ); 190 | name = "Supporting Files"; 191 | sourceTree = ""; 192 | }; 193 | B6F22D3118AC03C700543816 /* Images */ = { 194 | isa = PBXGroup; 195 | children = ( 196 | B6F22D3218AC03C700543816 /* VENCalculatorIconBackspace.png */, 197 | B6F22D3318AC03C700543816 /* VENCalculatorIconBackspace@2x.png */, 198 | 1AA4581A1B33ED8400708FFE /* VENCalculatorIconBackspace@3x.png */, 199 | ); 200 | path = Images; 201 | sourceTree = ""; 202 | }; 203 | /* End PBXGroup section */ 204 | 205 | /* Begin PBXNativeTarget section */ 206 | B6F22CF818AC031000543816 /* VENCalculatorInputView */ = { 207 | isa = PBXNativeTarget; 208 | buildConfigurationList = B6F22D1C18AC031100543816 /* Build configuration list for PBXNativeTarget "VENCalculatorInputView" */; 209 | buildPhases = ( 210 | B6F22CF518AC031000543816 /* Sources */, 211 | B6F22CF618AC031000543816 /* Frameworks */, 212 | B6F22CF718AC031000543816 /* CopyFiles */, 213 | ); 214 | buildRules = ( 215 | ); 216 | dependencies = ( 217 | ); 218 | name = VENCalculatorInputView; 219 | productName = VENCalculatorInputView; 220 | productReference = B6F22CF918AC031100543816 /* libVENCalculatorInputView.a */; 221 | productType = "com.apple.product-type.library.static"; 222 | }; 223 | B6F22D0818AC031100543816 /* VENCalculatorInputViewTests */ = { 224 | isa = PBXNativeTarget; 225 | buildConfigurationList = B6F22D1F18AC031100543816 /* Build configuration list for PBXNativeTarget "VENCalculatorInputViewTests" */; 226 | buildPhases = ( 227 | A953CD3FA4524205B403029C /* Check Pods Manifest.lock */, 228 | B6F22D0518AC031100543816 /* Sources */, 229 | B6F22D0618AC031100543816 /* Frameworks */, 230 | B6F22D0718AC031100543816 /* Resources */, 231 | 6AB4C71D215E43C6ABADF28B /* Copy Pods Resources */, 232 | ); 233 | buildRules = ( 234 | ); 235 | dependencies = ( 236 | B6F22D1018AC031100543816 /* PBXTargetDependency */, 237 | ); 238 | name = VENCalculatorInputViewTests; 239 | productName = VENCalculatorInputViewTests; 240 | productReference = B6F22D0918AC031100543816 /* VENCalculatorInputViewTests.xctest */; 241 | productType = "com.apple.product-type.bundle.unit-test"; 242 | }; 243 | /* End PBXNativeTarget section */ 244 | 245 | /* Begin PBXProject section */ 246 | B6F22CF118AC031000543816 /* Project object */ = { 247 | isa = PBXProject; 248 | attributes = { 249 | LastUpgradeCheck = 0500; 250 | ORGANIZATIONNAME = Venmo; 251 | }; 252 | buildConfigurationList = B6F22CF418AC031000543816 /* Build configuration list for PBXProject "VENCalculatorInputView" */; 253 | compatibilityVersion = "Xcode 3.2"; 254 | developmentRegion = English; 255 | hasScannedForEncodings = 0; 256 | knownRegions = ( 257 | en, 258 | ); 259 | mainGroup = B6F22CF018AC031000543816; 260 | productRefGroup = B6F22CFA18AC031100543816 /* Products */; 261 | projectDirPath = ""; 262 | projectRoot = ""; 263 | targets = ( 264 | B6F22CF818AC031000543816 /* VENCalculatorInputView */, 265 | B6F22D0818AC031100543816 /* VENCalculatorInputViewTests */, 266 | ); 267 | }; 268 | /* End PBXProject section */ 269 | 270 | /* Begin PBXResourcesBuildPhase section */ 271 | B6F22D0718AC031100543816 /* Resources */ = { 272 | isa = PBXResourcesBuildPhase; 273 | buildActionMask = 2147483647; 274 | files = ( 275 | 1AA4581B1B33ED8400708FFE /* VENCalculatorIconBackspace@3x.png in Resources */, 276 | B6F22D3418AC03C700543816 /* VENCalculatorIconBackspace.png in Resources */, 277 | B6F22D1718AC031100543816 /* InfoPlist.strings in Resources */, 278 | B6F22D3518AC03C700543816 /* VENCalculatorIconBackspace@2x.png in Resources */, 279 | ); 280 | runOnlyForDeploymentPostprocessing = 0; 281 | }; 282 | /* End PBXResourcesBuildPhase section */ 283 | 284 | /* Begin PBXShellScriptBuildPhase section */ 285 | 6AB4C71D215E43C6ABADF28B /* Copy Pods Resources */ = { 286 | isa = PBXShellScriptBuildPhase; 287 | buildActionMask = 2147483647; 288 | files = ( 289 | ); 290 | inputPaths = ( 291 | ); 292 | name = "Copy Pods Resources"; 293 | outputPaths = ( 294 | ); 295 | runOnlyForDeploymentPostprocessing = 0; 296 | shellPath = /bin/sh; 297 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-VENCalculatorInputViewTests/Pods-VENCalculatorInputViewTests-resources.sh\"\n"; 298 | showEnvVarsInLog = 0; 299 | }; 300 | A953CD3FA4524205B403029C /* Check Pods Manifest.lock */ = { 301 | isa = PBXShellScriptBuildPhase; 302 | buildActionMask = 2147483647; 303 | files = ( 304 | ); 305 | inputPaths = ( 306 | ); 307 | name = "Check Pods Manifest.lock"; 308 | outputPaths = ( 309 | ); 310 | runOnlyForDeploymentPostprocessing = 0; 311 | shellPath = /bin/sh; 312 | 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"; 313 | showEnvVarsInLog = 0; 314 | }; 315 | /* End PBXShellScriptBuildPhase section */ 316 | 317 | /* Begin PBXSourcesBuildPhase section */ 318 | B6F22CF518AC031000543816 /* Sources */ = { 319 | isa = PBXSourcesBuildPhase; 320 | buildActionMask = 2147483647; 321 | files = ( 322 | B6FD6362196BAB8700D1913C /* NSString+VENCalculatorInputView.m in Sources */, 323 | B6F22D3018AC039F00543816 /* VENCalculatorInputView.m in Sources */, 324 | B6F22D2E18AC039F00543816 /* VENMoneyCalculator.m in Sources */, 325 | B6F22D2F18AC039F00543816 /* VENCalculatorInputTextField.m in Sources */, 326 | 2F74D09D196F533B0040C816 /* UITextField+VENCalculatorInputView.m in Sources */, 327 | ); 328 | runOnlyForDeploymentPostprocessing = 0; 329 | }; 330 | B6F22D0518AC031100543816 /* Sources */ = { 331 | isa = PBXSourcesBuildPhase; 332 | buildActionMask = 2147483647; 333 | files = ( 334 | 2F74D09F196F53E20040C816 /* UITextField+VENCalculatorInputViewSpec.m in Sources */, 335 | B6F22D2318AC039100543816 /* VENMoneyCalculatorSpec.m in Sources */, 336 | B6FD6364196BB09D00D1913C /* NSString+VENCalculatorInputViewSpec.m in Sources */, 337 | ); 338 | runOnlyForDeploymentPostprocessing = 0; 339 | }; 340 | /* End PBXSourcesBuildPhase section */ 341 | 342 | /* Begin PBXTargetDependency section */ 343 | B6F22D1018AC031100543816 /* PBXTargetDependency */ = { 344 | isa = PBXTargetDependency; 345 | target = B6F22CF818AC031000543816 /* VENCalculatorInputView */; 346 | targetProxy = B6F22D0F18AC031100543816 /* PBXContainerItemProxy */; 347 | }; 348 | /* End PBXTargetDependency section */ 349 | 350 | /* Begin PBXVariantGroup section */ 351 | B6F22D1518AC031100543816 /* InfoPlist.strings */ = { 352 | isa = PBXVariantGroup; 353 | children = ( 354 | B6F22D1618AC031100543816 /* en */, 355 | ); 356 | name = InfoPlist.strings; 357 | sourceTree = ""; 358 | }; 359 | /* End PBXVariantGroup section */ 360 | 361 | /* Begin XCBuildConfiguration section */ 362 | B6F22D1A18AC031100543816 /* Debug */ = { 363 | isa = XCBuildConfiguration; 364 | buildSettings = { 365 | ALWAYS_SEARCH_USER_PATHS = NO; 366 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; 367 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 368 | CLANG_CXX_LIBRARY = "libc++"; 369 | CLANG_ENABLE_MODULES = YES; 370 | CLANG_ENABLE_OBJC_ARC = YES; 371 | CLANG_WARN_BOOL_CONVERSION = YES; 372 | CLANG_WARN_CONSTANT_CONVERSION = YES; 373 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 374 | CLANG_WARN_EMPTY_BODY = YES; 375 | CLANG_WARN_ENUM_CONVERSION = YES; 376 | CLANG_WARN_INT_CONVERSION = YES; 377 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 378 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 379 | COPY_PHASE_STRIP = NO; 380 | GCC_C_LANGUAGE_STANDARD = gnu99; 381 | GCC_DYNAMIC_NO_PIC = NO; 382 | GCC_OPTIMIZATION_LEVEL = 0; 383 | GCC_PREPROCESSOR_DEFINITIONS = ( 384 | "DEBUG=1", 385 | "$(inherited)", 386 | ); 387 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 388 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 389 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 390 | GCC_WARN_UNDECLARED_SELECTOR = YES; 391 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 392 | GCC_WARN_UNUSED_FUNCTION = YES; 393 | GCC_WARN_UNUSED_VARIABLE = YES; 394 | IPHONEOS_DEPLOYMENT_TARGET = 5.0; 395 | ONLY_ACTIVE_ARCH = YES; 396 | SDKROOT = iphoneos; 397 | }; 398 | name = Debug; 399 | }; 400 | B6F22D1B18AC031100543816 /* Release */ = { 401 | isa = XCBuildConfiguration; 402 | buildSettings = { 403 | ALWAYS_SEARCH_USER_PATHS = NO; 404 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; 405 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 406 | CLANG_CXX_LIBRARY = "libc++"; 407 | CLANG_ENABLE_MODULES = YES; 408 | CLANG_ENABLE_OBJC_ARC = YES; 409 | CLANG_WARN_BOOL_CONVERSION = YES; 410 | CLANG_WARN_CONSTANT_CONVERSION = YES; 411 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 412 | CLANG_WARN_EMPTY_BODY = YES; 413 | CLANG_WARN_ENUM_CONVERSION = YES; 414 | CLANG_WARN_INT_CONVERSION = YES; 415 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 416 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 417 | COPY_PHASE_STRIP = YES; 418 | ENABLE_NS_ASSERTIONS = NO; 419 | GCC_C_LANGUAGE_STANDARD = gnu99; 420 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 421 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 422 | GCC_WARN_UNDECLARED_SELECTOR = YES; 423 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 424 | GCC_WARN_UNUSED_FUNCTION = YES; 425 | GCC_WARN_UNUSED_VARIABLE = YES; 426 | IPHONEOS_DEPLOYMENT_TARGET = 5.0; 427 | SDKROOT = iphoneos; 428 | VALIDATE_PRODUCT = YES; 429 | }; 430 | name = Release; 431 | }; 432 | B6F22D1D18AC031100543816 /* Debug */ = { 433 | isa = XCBuildConfiguration; 434 | buildSettings = { 435 | DSTROOT = /tmp/VENCalculatorInputView.dst; 436 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 437 | GCC_PREFIX_HEADER = "VENCalculatorInputView/VENCalculatorInputView-Prefix.pch"; 438 | OTHER_LDFLAGS = "-ObjC"; 439 | PRODUCT_NAME = "$(TARGET_NAME)"; 440 | SKIP_INSTALL = YES; 441 | }; 442 | name = Debug; 443 | }; 444 | B6F22D1E18AC031100543816 /* Release */ = { 445 | isa = XCBuildConfiguration; 446 | buildSettings = { 447 | DSTROOT = /tmp/VENCalculatorInputView.dst; 448 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 449 | GCC_PREFIX_HEADER = "VENCalculatorInputView/VENCalculatorInputView-Prefix.pch"; 450 | OTHER_LDFLAGS = "-ObjC"; 451 | PRODUCT_NAME = "$(TARGET_NAME)"; 452 | SKIP_INSTALL = YES; 453 | }; 454 | name = Release; 455 | }; 456 | B6F22D2018AC031100543816 /* Debug */ = { 457 | isa = XCBuildConfiguration; 458 | baseConfigurationReference = 382246DCE4C0E18FFC29538F /* Pods-VENCalculatorInputViewTests.debug.xcconfig */; 459 | buildSettings = { 460 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; 461 | FRAMEWORK_SEARCH_PATHS = ( 462 | "$(SDKROOT)/Developer/Library/Frameworks", 463 | "$(inherited)", 464 | "$(DEVELOPER_FRAMEWORKS_DIR)", 465 | ); 466 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 467 | GCC_PREFIX_HEADER = "VENCalculatorInputView/VENCalculatorInputView-Prefix.pch"; 468 | GCC_PREPROCESSOR_DEFINITIONS = ( 469 | "DEBUG=1", 470 | "$(inherited)", 471 | ); 472 | INFOPLIST_FILE = "VENCalculatorInputViewTests/VENCalculatorInputViewTests-Info.plist"; 473 | PRODUCT_NAME = "$(TARGET_NAME)"; 474 | WRAPPER_EXTENSION = xctest; 475 | }; 476 | name = Debug; 477 | }; 478 | B6F22D2118AC031100543816 /* Release */ = { 479 | isa = XCBuildConfiguration; 480 | baseConfigurationReference = BA38E94872D6B1E128555B04 /* Pods-VENCalculatorInputViewTests.release.xcconfig */; 481 | buildSettings = { 482 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; 483 | FRAMEWORK_SEARCH_PATHS = ( 484 | "$(SDKROOT)/Developer/Library/Frameworks", 485 | "$(inherited)", 486 | "$(DEVELOPER_FRAMEWORKS_DIR)", 487 | ); 488 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 489 | GCC_PREFIX_HEADER = "VENCalculatorInputView/VENCalculatorInputView-Prefix.pch"; 490 | INFOPLIST_FILE = "VENCalculatorInputViewTests/VENCalculatorInputViewTests-Info.plist"; 491 | PRODUCT_NAME = "$(TARGET_NAME)"; 492 | WRAPPER_EXTENSION = xctest; 493 | }; 494 | name = Release; 495 | }; 496 | /* End XCBuildConfiguration section */ 497 | 498 | /* Begin XCConfigurationList section */ 499 | B6F22CF418AC031000543816 /* Build configuration list for PBXProject "VENCalculatorInputView" */ = { 500 | isa = XCConfigurationList; 501 | buildConfigurations = ( 502 | B6F22D1A18AC031100543816 /* Debug */, 503 | B6F22D1B18AC031100543816 /* Release */, 504 | ); 505 | defaultConfigurationIsVisible = 0; 506 | defaultConfigurationName = Release; 507 | }; 508 | B6F22D1C18AC031100543816 /* Build configuration list for PBXNativeTarget "VENCalculatorInputView" */ = { 509 | isa = XCConfigurationList; 510 | buildConfigurations = ( 511 | B6F22D1D18AC031100543816 /* Debug */, 512 | B6F22D1E18AC031100543816 /* Release */, 513 | ); 514 | defaultConfigurationIsVisible = 0; 515 | defaultConfigurationName = Release; 516 | }; 517 | B6F22D1F18AC031100543816 /* Build configuration list for PBXNativeTarget "VENCalculatorInputViewTests" */ = { 518 | isa = XCConfigurationList; 519 | buildConfigurations = ( 520 | B6F22D2018AC031100543816 /* Debug */, 521 | B6F22D2118AC031100543816 /* Release */, 522 | ); 523 | defaultConfigurationIsVisible = 0; 524 | defaultConfigurationName = Release; 525 | }; 526 | /* End XCConfigurationList section */ 527 | }; 528 | rootObject = B6F22CF118AC031000543816 /* Project object */; 529 | } 530 | -------------------------------------------------------------------------------- /VENCalculatorInputView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /VENCalculatorInputView.xcodeproj/xcshareddata/xcschemes/VENCalculatorInputView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 52 | 53 | 54 | 55 | 61 | 62 | 64 | 65 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /VENCalculatorInputView.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /VENCalculatorInputView.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /VENCalculatorInputView/Images/VENCalculatorIconBackspace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/venmo/VENCalculatorInputView/0cf20218ca52ea98e9bc7598c843c3b34d971e52/VENCalculatorInputView/Images/VENCalculatorIconBackspace.png -------------------------------------------------------------------------------- /VENCalculatorInputView/Images/VENCalculatorIconBackspace@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/venmo/VENCalculatorInputView/0cf20218ca52ea98e9bc7598c843c3b34d971e52/VENCalculatorInputView/Images/VENCalculatorIconBackspace@2x.png -------------------------------------------------------------------------------- /VENCalculatorInputView/Images/VENCalculatorIconBackspace@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/venmo/VENCalculatorInputView/0cf20218ca52ea98e9bc7598c843c3b34d971e52/VENCalculatorInputView/Images/VENCalculatorIconBackspace@3x.png -------------------------------------------------------------------------------- /VENCalculatorInputView/NSString+VENCalculatorInputView.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface NSString (VENCalculatorInputView) 4 | 5 | - (NSString *)stringByReplacingCharactersInSet:(NSCharacterSet *)characterSet 6 | withString:(NSString *)string; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /VENCalculatorInputView/NSString+VENCalculatorInputView.m: -------------------------------------------------------------------------------- 1 | #import "NSString+VENCalculatorInputView.h" 2 | 3 | @implementation NSString (VENCalculatorInputView) 4 | 5 | - (NSString *)stringByReplacingCharactersInSet:(NSCharacterSet *)characterSet 6 | withString:(NSString *)string 7 | { 8 | return [[self componentsSeparatedByCharactersInSet:characterSet] componentsJoinedByString:string]; 9 | } 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /VENCalculatorInputView/UITextField+VENCalculatorInputView.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface UITextField (VENCalculatorInputView) 4 | 5 | - (NSRange)selectedNSRange; 6 | 7 | @end 8 | -------------------------------------------------------------------------------- /VENCalculatorInputView/UITextField+VENCalculatorInputView.m: -------------------------------------------------------------------------------- 1 | #import "UITextField+VENCalculatorInputView.h" 2 | 3 | @implementation UITextField (VENCalculatorInputView) 4 | 5 | - (NSRange)selectedNSRange 6 | { 7 | UITextPosition *beginning = self.beginningOfDocument; 8 | 9 | UITextRange *selectedRange = self.selectedTextRange; 10 | UITextPosition *selectionStart = selectedRange.start; 11 | UITextPosition *selectionEnd = selectedRange.end; 12 | 13 | NSInteger location = [self offsetFromPosition:beginning toPosition:selectionStart]; 14 | NSInteger length = [self offsetFromPosition:selectionStart toPosition:selectionEnd]; 15 | 16 | return NSMakeRange(location, length); 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /VENCalculatorInputView/VENCalculatorInputTextField.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "VENCalculatorInputView.h" 3 | 4 | @interface VENCalculatorInputTextField : UITextField 5 | 6 | /** 7 | The locale to use for the decimal separator. 8 | Defaults to locale for current device. 9 | */ 10 | @property (strong, nonatomic) NSLocale *locale; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /VENCalculatorInputView/VENCalculatorInputTextField.m: -------------------------------------------------------------------------------- 1 | #import "VENCalculatorInputTextField.h" 2 | #import "VENMoneyCalculator.h" 3 | #import "UITextField+VENCalculatorInputView.h" 4 | 5 | @interface VENCalculatorInputTextField () 6 | @property (strong, nonatomic) VENMoneyCalculator *moneyCalculator; 7 | @end 8 | 9 | @implementation VENCalculatorInputTextField 10 | 11 | - (id)initWithFrame:(CGRect)frame { 12 | self = [super initWithFrame:frame]; 13 | if (self) { 14 | [self setUpInit]; 15 | } 16 | return self; 17 | } 18 | 19 | - (void)awakeFromNib { 20 | [self setUpInit]; 21 | } 22 | 23 | - (void)setUpInit { 24 | self.locale = [NSLocale currentLocale]; 25 | 26 | VENCalculatorInputView *inputView = [VENCalculatorInputView new]; 27 | inputView.delegate = self; 28 | inputView.locale = self.locale; 29 | self.inputView = inputView; 30 | 31 | VENMoneyCalculator *moneyCalculator = [VENMoneyCalculator new]; 32 | moneyCalculator.locale = self.locale; 33 | self.moneyCalculator = moneyCalculator; 34 | 35 | [self addTarget:self action:@selector(venCalculatorTextFieldDidEndEditing) forControlEvents:UIControlEventEditingDidEnd]; 36 | } 37 | 38 | 39 | #pragma mark - Properties 40 | 41 | - (void)setLocale:(NSLocale *)locale { 42 | _locale = locale; 43 | VENCalculatorInputView *inputView = (VENCalculatorInputView *)self.inputView; 44 | inputView.locale = locale; 45 | self.moneyCalculator.locale = locale; 46 | } 47 | 48 | 49 | #pragma mark - UITextField 50 | 51 | - (void)venCalculatorTextFieldDidEndEditing { 52 | NSString *textToEvaluate = [self trimExpressionString:self.text]; 53 | NSString *evaluatedString = [self.moneyCalculator evaluateExpression:textToEvaluate]; 54 | if (evaluatedString) { 55 | self.text = evaluatedString; 56 | } 57 | } 58 | 59 | 60 | #pragma mark - VENCalculatorInputViewDelegate 61 | 62 | - (void)calculatorInputView:(VENCalculatorInputView *)inputView didTapKey:(NSString *)key { 63 | if ([self.delegate respondsToSelector:@selector(textField:shouldChangeCharactersInRange:replacementString:)]) { 64 | NSRange range = [self selectedNSRange]; 65 | if (![self.delegate textField:self shouldChangeCharactersInRange:range replacementString:key]) { 66 | return; 67 | } 68 | } 69 | 70 | [self insertText:key]; 71 | NSString *subString = [self.text substringToIndex:self.text.length - 1]; 72 | if ([key isEqualToString:@"+"] || 73 | [key isEqualToString:@"−"] || 74 | [key isEqualToString:@"×"] || 75 | [key isEqualToString:@"÷"]) { 76 | NSString *evaluatedString = [self.moneyCalculator evaluateExpression:[self trimExpressionString:subString]]; 77 | if (evaluatedString) { 78 | self.text = [NSString stringWithFormat:@"%@%@", evaluatedString, key]; 79 | } else { 80 | self.text = subString; 81 | } 82 | } else if ([key isEqualToString:[self decimalSeparator]]) { 83 | NSString *secondToLastCharacterString = [self.text substringWithRange:NSMakeRange([self.text length] - 2, 1)]; 84 | if ([secondToLastCharacterString isEqualToString:[self decimalSeparator]]) { 85 | self.text = subString; 86 | } 87 | } 88 | } 89 | 90 | - (void)calculatorInputViewDidTapBackspace:(VENCalculatorInputView *)calculatorInputView { 91 | [self deleteBackward]; 92 | } 93 | 94 | 95 | #pragma mark - Helpers 96 | 97 | /** 98 | Removes any trailing operations and decimals. 99 | @param expressionString The expression string to trim 100 | @return The trimmed expression string 101 | */ 102 | - (NSString *)trimExpressionString:(NSString *)expressionString { 103 | NSString *txt = self.text; 104 | while ([txt length] > 0) { 105 | NSString *lastCharacterString = [txt substringFromIndex:[txt length] - 1]; 106 | if ([lastCharacterString isEqualToString:@"+"] || 107 | [lastCharacterString isEqualToString:@"−"] || 108 | [lastCharacterString isEqualToString:@"×"] || 109 | [lastCharacterString isEqualToString:@"÷"] || 110 | [lastCharacterString isEqualToString:self.decimalSeparator]) { 111 | txt = [txt substringToIndex:txt.length - 1]; 112 | } 113 | else { 114 | break; 115 | } 116 | } 117 | return txt; 118 | } 119 | 120 | - (NSString *)decimalSeparator { 121 | return [self.locale objectForKey:NSLocaleDecimalSeparator]; 122 | } 123 | 124 | @end 125 | -------------------------------------------------------------------------------- /VENCalculatorInputView/VENCalculatorInputView-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #ifdef __OBJC__ 8 | #import 9 | #import 10 | #endif 11 | -------------------------------------------------------------------------------- /VENCalculatorInputView/VENCalculatorInputView.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class VENCalculatorInputView; 4 | @protocol VENCalculatorInputViewDelegate 5 | 6 | @optional 7 | - (void)calculatorInputView:(VENCalculatorInputView *)inputView didTapKey:(NSString *)key; 8 | - (void)calculatorInputViewDidTapBackspace:(VENCalculatorInputView *)calculatorInputView; 9 | 10 | @end 11 | 12 | @interface VENCalculatorInputView : UIView 13 | 14 | @property (weak, nonatomic) id delegate; 15 | 16 | /**----------------------------------------------------------------------------- 17 | * @name Localization 18 | * ----------------------------------------------------------------------------- 19 | */ 20 | 21 | /** 22 | The locale to use for the decimal separator. 23 | Defaults to locale for current device. 24 | */ 25 | @property (strong, nonatomic) NSLocale *locale; 26 | 27 | 28 | /**----------------------------------------------------------------------------- 29 | * @name Customizing colors 30 | * ----------------------------------------------------------------------------- 31 | */ 32 | 33 | @property (strong, nonatomic) UIColor *buttonTitleColor; 34 | @property (strong, nonatomic) UIFont *buttonTitleFont; 35 | @property (strong, nonatomic) UIColor *buttonHighlightedColor; 36 | 37 | @property (strong, nonatomic) UIColor *numberButtonBackgroundColor; 38 | @property (strong, nonatomic) UIColor *numberButtonBorderColor; 39 | 40 | @property (strong, nonatomic) UIColor *operationButtonBackgroundColor; 41 | @property (strong, nonatomic) UIColor *operationButtonBorderColor; 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /VENCalculatorInputView/VENCalculatorInputView.m: -------------------------------------------------------------------------------- 1 | #import "VENCalculatorInputView.h" 2 | 3 | @interface VENCalculatorInputView () 4 | 5 | @property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *numberButtonCollection; 6 | @property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *operationButtonCollection; 7 | @property (strong, nonatomic) IBOutlet UIButton *decimalButton; 8 | 9 | @end 10 | 11 | @implementation VENCalculatorInputView 12 | 13 | - (id)initWithFrame:(CGRect)frame { 14 | self = [[[NSBundle bundleForClass:[self class]] loadNibNamed:@"VENCalculatorInputView" owner:self options:nil] firstObject]; 15 | if (self) { 16 | // Set default locale 17 | self.locale = [NSLocale currentLocale]; 18 | 19 | // Set customizable properties 20 | [self setNumberButtonBackgroundColor:[UIColor colorWithWhite:0.98828 alpha:1]]; 21 | [self setNumberButtonBorderColor:[UIColor colorWithRed:193/255.0f green:195/255.0f blue:199/255.0f alpha:1]]; 22 | [self setOperationButtonBackgroundColor:[UIColor colorWithRed:193/255.0f green:196/255.0f blue:200/255.0f alpha:1]]; 23 | [self setOperationButtonBorderColor:[UIColor colorWithRed:172/255.0f green:174/255.0f blue:177/255.0f alpha:1]]; 24 | [self setButtonHighlightedColor:[UIColor grayColor]]; 25 | [self setButtonTitleColor:[UIColor darkTextColor]]; 26 | 27 | // Set default properties 28 | for (UIButton *numberButton in self.numberButtonCollection) { 29 | [self setupButton:numberButton]; 30 | } 31 | for (UIButton *operationButton in self.operationButtonCollection) { 32 | [self setupButton:operationButton]; 33 | } 34 | } 35 | return self; 36 | } 37 | 38 | - (void)setLocale:(NSLocale *)locale { 39 | _locale = locale; 40 | NSString *decimalSymbol = [locale objectForKey:NSLocaleDecimalSeparator]; 41 | [self.decimalButton setTitle:decimalSymbol forState:UIControlStateNormal]; 42 | } 43 | 44 | - (void)setupButton:(UIButton *)button { 45 | button.layer.borderWidth = 0.25f; 46 | } 47 | 48 | - (IBAction)userDidTapBackspace:(UIButton *)sender { 49 | [[UIDevice currentDevice] playInputClick]; 50 | if ([self.delegate respondsToSelector:@selector(calculatorInputViewDidTapBackspace:)]) { 51 | [self.delegate calculatorInputViewDidTapBackspace:self]; 52 | } 53 | } 54 | 55 | - (IBAction)userDidTapKey:(UIButton *)sender { 56 | [[UIDevice currentDevice] playInputClick]; 57 | if ([self.delegate respondsToSelector:@selector(calculatorInputView:didTapKey:)]) { 58 | [self.delegate calculatorInputView:self didTapKey:sender.titleLabel.text]; 59 | } 60 | } 61 | 62 | 63 | #pragma mark - UIInputViewAudioFeedback 64 | 65 | - (BOOL)enableInputClicksWhenVisible { 66 | return YES; 67 | } 68 | 69 | 70 | #pragma mark - Helpers 71 | 72 | - (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size { 73 | UIGraphicsBeginImageContextWithOptions(size, NO, 0); 74 | CGContextRef context = UIGraphicsGetCurrentContext(); 75 | 76 | [color set]; 77 | CGContextFillRect(context, CGRectMake(0, 0, size.width, size.height)); 78 | 79 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 80 | UIGraphicsEndImageContext(); 81 | return image; 82 | } 83 | 84 | 85 | #pragma mark - Properties 86 | 87 | - (void)setButtonTitleColor:(UIColor *)buttonTitleColor { 88 | _buttonTitleColor = buttonTitleColor; 89 | for (UIButton *numberButton in self.numberButtonCollection) { 90 | [numberButton setTitleColor:buttonTitleColor forState:UIControlStateNormal]; 91 | } 92 | for (UIButton *operationButton in self.operationButtonCollection) { 93 | [operationButton setTitleColor:buttonTitleColor forState:UIControlStateNormal]; 94 | } 95 | } 96 | 97 | - (void)setButtonTitleFont:(UIFont *)buttonTitleFont { 98 | _buttonTitleFont = buttonTitleFont; 99 | for (UIButton *numberButton in self.numberButtonCollection) { 100 | numberButton.titleLabel.font = buttonTitleFont; 101 | } 102 | for (UIButton *operationButton in self.operationButtonCollection) { 103 | operationButton.titleLabel.font = buttonTitleFont; 104 | } 105 | } 106 | 107 | - (void)setButtonHighlightedColor:(UIColor *)buttonHighlightedColor { 108 | _buttonHighlightedColor = buttonHighlightedColor; 109 | for (UIButton *numberButton in self.numberButtonCollection) { 110 | [numberButton setBackgroundImage:[self imageWithColor:buttonHighlightedColor size:CGSizeMake(50, 50)] 111 | forState:UIControlStateHighlighted]; 112 | } 113 | for (UIButton *operationButton in self.operationButtonCollection) { 114 | [operationButton setBackgroundImage:[self imageWithColor:buttonHighlightedColor size:CGSizeMake(50, 50)] 115 | forState:UIControlStateHighlighted]; 116 | } 117 | } 118 | 119 | - (void)setNumberButtonBackgroundColor:(UIColor *)numberButtonBackgroundColor { 120 | _numberButtonBackgroundColor = numberButtonBackgroundColor; 121 | for (UIButton *numberButton in self.numberButtonCollection) { 122 | numberButton.backgroundColor = numberButtonBackgroundColor; 123 | } 124 | } 125 | 126 | - (void)setNumberButtonBorderColor:(UIColor *)numberButtonBorderColor { 127 | _numberButtonBorderColor = numberButtonBorderColor; 128 | for (UIButton *numberButton in self.numberButtonCollection) { 129 | numberButton.layer.borderColor = numberButtonBorderColor.CGColor; 130 | } 131 | } 132 | 133 | - (void)setOperationButtonBackgroundColor:(UIColor *)operationButtonBackgroundColor { 134 | _operationButtonBackgroundColor = operationButtonBackgroundColor; 135 | for (UIButton *operationButton in self.operationButtonCollection) { 136 | operationButton.backgroundColor = operationButtonBackgroundColor; 137 | } 138 | } 139 | 140 | - (void)setOperationButtonBorderColor:(UIColor *)operationButtonBorderColor { 141 | _operationButtonBorderColor = operationButtonBorderColor; 142 | for (UIButton *operationButton in self.operationButtonCollection) { 143 | operationButton.layer.borderColor = operationButtonBorderColor.CGColor; 144 | } 145 | } 146 | 147 | @end 148 | -------------------------------------------------------------------------------- /VENCalculatorInputView/VENCalculatorInputView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 25 | 36 | 47 | 58 | 69 | 80 | 91 | 102 | 113 | 124 | 135 | 146 | 157 | 168 | 179 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | -------------------------------------------------------------------------------- /VENCalculatorInputView/VENMoneyCalculator.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface VENMoneyCalculator : NSObject 4 | 5 | @property (strong, nonatomic) NSLocale *locale; 6 | 7 | /** 8 | * Evaluates a mathematical expression containing +, −, ×, and ÷. 9 | * @param expression The expression to evaluate 10 | * @return The evaluated expression. Returns nil if the expression is invalid. 11 | */ 12 | - (NSString *)evaluateExpression:(NSString *)expression; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /VENCalculatorInputView/VENMoneyCalculator.m: -------------------------------------------------------------------------------- 1 | #import "VENMoneyCalculator.h" 2 | #import "NSString+VENCalculatorInputView.h" 3 | 4 | @interface VENMoneyCalculator () 5 | @property (strong, nonatomic) NSNumberFormatter *numberFormatter; 6 | @end 7 | 8 | @implementation VENMoneyCalculator 9 | 10 | - (instancetype)init { 11 | self = [super init]; 12 | if (self) { 13 | self.locale = [NSLocale currentLocale]; 14 | } 15 | return self; 16 | } 17 | 18 | - (NSString *)evaluateExpression:(NSString *)expressionString { 19 | if (!expressionString) { 20 | return nil; 21 | } 22 | NSString *sanitizedString = [self sanitizedString:expressionString]; 23 | NSString *floatString = [NSString stringWithFormat:@"1.0*%@", sanitizedString]; 24 | NSExpression *expression; 25 | id result; 26 | @try { 27 | expression = [NSExpression expressionWithFormat:floatString]; 28 | result = [expression expressionValueWithObject:nil context:nil]; 29 | } 30 | @catch (NSException *exception) { 31 | if ([[exception name] isEqualToString:NSInvalidArgumentException]) { 32 | return nil; 33 | } else { 34 | [exception raise]; 35 | } 36 | } 37 | if ([result isKindOfClass:[NSNumber class]]) { 38 | NSInteger integerExpression = [(NSNumber *)result integerValue]; 39 | CGFloat floatExpression = [(NSNumber *)result floatValue]; 40 | if (integerExpression == floatExpression) { 41 | return [(NSNumber *)result stringValue]; 42 | } else if (floatExpression >= CGFLOAT_MAX || floatExpression <= CGFLOAT_MIN || isnan(floatExpression)) { 43 | return @"0"; 44 | } else { 45 | NSString *moneyFormattedNumber = [[self numberFormatter] stringFromNumber:@(floatExpression)]; 46 | return [moneyFormattedNumber stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 47 | } 48 | } else { 49 | return nil; 50 | } 51 | } 52 | 53 | - (void)setLocale:(NSLocale *)locale { 54 | _locale = locale; 55 | self.numberFormatter.locale = locale; 56 | } 57 | 58 | 59 | #pragma mark - Private 60 | 61 | - (NSNumberFormatter *)numberFormatter { 62 | if (!_numberFormatter) { 63 | _numberFormatter = [NSNumberFormatter new]; 64 | [_numberFormatter setLocale:self.locale]; 65 | [_numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle]; 66 | [_numberFormatter setCurrencySymbol:@""]; 67 | } 68 | return _numberFormatter; 69 | } 70 | 71 | - (NSString *)sanitizedString:(NSString *)string { 72 | NSString *groupingSeperator = [self.locale objectForKey:NSLocaleGroupingSeparator]; 73 | NSString *withoutGroupingSeperator = [string stringByReplacingOccurrencesOfString:groupingSeperator withString:@""]; 74 | return [[self replaceOperandsInString:withoutGroupingSeperator] stringByReplacingCharactersInSet:[self illegalCharacters] withString:@""]; 75 | } 76 | 77 | - (NSString *)replaceOperandsInString:(NSString *)string { 78 | NSString *subtractReplaced = [string stringByReplacingOccurrencesOfString:@"−" withString:@"-"]; 79 | NSString *divideReplaced = [subtractReplaced stringByReplacingOccurrencesOfString:@"÷" withString:@"/"]; 80 | NSString *multiplyReplaced = [divideReplaced stringByReplacingOccurrencesOfString:@"×" withString:@"*"]; 81 | 82 | return [multiplyReplaced stringByReplacingOccurrencesOfString:[self decimalSeparator] withString:@"."]; 83 | } 84 | 85 | - (NSCharacterSet *)illegalCharacters { 86 | return [[NSCharacterSet characterSetWithCharactersInString:@"0123456789-/*.+"] invertedSet]; 87 | } 88 | 89 | - (NSString *)decimalSeparator { 90 | return [self.locale objectForKey:NSLocaleDecimalSeparator]; 91 | } 92 | 93 | @end 94 | -------------------------------------------------------------------------------- /VENCalculatorInputViewSample/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '5.0' 2 | inhibit_all_warnings! 3 | 4 | target 'VENCalculatorInputViewSample', :exclusive => true do 5 | pod 'VENCalculatorInputView', :path => './../' 6 | end 7 | -------------------------------------------------------------------------------- /VENCalculatorInputViewSample/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - VENCalculatorInputView (1.5.4) 3 | 4 | DEPENDENCIES: 5 | - VENCalculatorInputView (from `./../`) 6 | 7 | EXTERNAL SOURCES: 8 | VENCalculatorInputView: 9 | :path: ./../ 10 | 11 | SPEC CHECKSUMS: 12 | VENCalculatorInputView: 988fa681ba6bb9b1f067842493bb622e80cc8da2 13 | 14 | COCOAPODS: 0.37.2 15 | -------------------------------------------------------------------------------- /VENCalculatorInputViewSample/VENCalculatorInputViewSample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 2CBB59849A1C47F0BF1325E8 /* libPods-VENCalculatorInputViewSample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E99D08981FEF415990879498 /* libPods-VENCalculatorInputViewSample.a */; }; 11 | B64A634B18AAB0990091A465 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B64A634A18AAB0990091A465 /* Foundation.framework */; }; 12 | B64A634D18AAB0990091A465 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B64A634C18AAB0990091A465 /* CoreGraphics.framework */; }; 13 | B64A634F18AAB0990091A465 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B64A634E18AAB0990091A465 /* UIKit.framework */; }; 14 | B64A635518AAB0990091A465 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = B64A635318AAB0990091A465 /* InfoPlist.strings */; }; 15 | B64A635718AAB0990091A465 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = B64A635618AAB0990091A465 /* main.m */; }; 16 | B64A635B18AAB0990091A465 /* VENAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = B64A635A18AAB0990091A465 /* VENAppDelegate.m */; }; 17 | B64A635E18AAB0990091A465 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B64A635C18AAB0990091A465 /* Main.storyboard */; }; 18 | B64A636118AAB0990091A465 /* VENViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B64A636018AAB0990091A465 /* VENViewController.m */; }; 19 | B64A636318AAB0990091A465 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B64A636218AAB0990091A465 /* Images.xcassets */; }; 20 | B64A636A18AAB0990091A465 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B64A636918AAB0990091A465 /* XCTest.framework */; }; 21 | B64A636B18AAB0990091A465 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B64A634A18AAB0990091A465 /* Foundation.framework */; }; 22 | B64A636C18AAB0990091A465 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B64A634E18AAB0990091A465 /* UIKit.framework */; }; 23 | B64A637418AAB09A0091A465 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = B64A637218AAB09A0091A465 /* InfoPlist.strings */; }; 24 | B64A637618AAB09A0091A465 /* VENCalculatorInputViewSampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B64A637518AAB09A0091A465 /* VENCalculatorInputViewSampleTests.m */; }; 25 | /* End PBXBuildFile section */ 26 | 27 | /* Begin PBXContainerItemProxy section */ 28 | B64A636D18AAB0990091A465 /* PBXContainerItemProxy */ = { 29 | isa = PBXContainerItemProxy; 30 | containerPortal = B64A633F18AAB0990091A465 /* Project object */; 31 | proxyType = 1; 32 | remoteGlobalIDString = B64A634618AAB0990091A465; 33 | remoteInfo = VENCalculatorInputViewSample; 34 | }; 35 | /* End PBXContainerItemProxy section */ 36 | 37 | /* Begin PBXFileReference section */ 38 | 220CB6253C40657765F007F6 /* Pods-VENCalculatorInputViewSample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VENCalculatorInputViewSample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-VENCalculatorInputViewSample/Pods-VENCalculatorInputViewSample.debug.xcconfig"; sourceTree = ""; }; 39 | B64A634718AAB0990091A465 /* VENCalculatorInputViewSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VENCalculatorInputViewSample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 40 | B64A634A18AAB0990091A465 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 41 | B64A634C18AAB0990091A465 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 42 | B64A634E18AAB0990091A465 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 43 | B64A635218AAB0990091A465 /* VENCalculatorInputViewSample-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "VENCalculatorInputViewSample-Info.plist"; sourceTree = ""; }; 44 | B64A635418AAB0990091A465 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 45 | B64A635618AAB0990091A465 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 46 | B64A635818AAB0990091A465 /* VENCalculatorInputViewSample-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "VENCalculatorInputViewSample-Prefix.pch"; sourceTree = ""; }; 47 | B64A635918AAB0990091A465 /* VENAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VENAppDelegate.h; sourceTree = ""; }; 48 | B64A635A18AAB0990091A465 /* VENAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VENAppDelegate.m; sourceTree = ""; }; 49 | B64A635D18AAB0990091A465 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 50 | B64A635F18AAB0990091A465 /* VENViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VENViewController.h; sourceTree = ""; }; 51 | B64A636018AAB0990091A465 /* VENViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VENViewController.m; sourceTree = ""; }; 52 | B64A636218AAB0990091A465 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 53 | B64A636818AAB0990091A465 /* VENCalculatorInputViewSampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = VENCalculatorInputViewSampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 54 | B64A636918AAB0990091A465 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 55 | B64A637118AAB0990091A465 /* VENCalculatorInputViewSampleTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "VENCalculatorInputViewSampleTests-Info.plist"; sourceTree = ""; }; 56 | B64A637318AAB09A0091A465 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 57 | B64A637518AAB09A0091A465 /* VENCalculatorInputViewSampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VENCalculatorInputViewSampleTests.m; sourceTree = ""; }; 58 | C38F1368BB419BF5E1EC2072 /* Pods-VENCalculatorInputViewSample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VENCalculatorInputViewSample.release.xcconfig"; path = "Pods/Target Support Files/Pods-VENCalculatorInputViewSample/Pods-VENCalculatorInputViewSample.release.xcconfig"; sourceTree = ""; }; 59 | E99D08981FEF415990879498 /* libPods-VENCalculatorInputViewSample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-VENCalculatorInputViewSample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 60 | /* End PBXFileReference section */ 61 | 62 | /* Begin PBXFrameworksBuildPhase section */ 63 | B64A634418AAB0990091A465 /* Frameworks */ = { 64 | isa = PBXFrameworksBuildPhase; 65 | buildActionMask = 2147483647; 66 | files = ( 67 | B64A634D18AAB0990091A465 /* CoreGraphics.framework in Frameworks */, 68 | B64A634F18AAB0990091A465 /* UIKit.framework in Frameworks */, 69 | B64A634B18AAB0990091A465 /* Foundation.framework in Frameworks */, 70 | 2CBB59849A1C47F0BF1325E8 /* libPods-VENCalculatorInputViewSample.a in Frameworks */, 71 | ); 72 | runOnlyForDeploymentPostprocessing = 0; 73 | }; 74 | B64A636518AAB0990091A465 /* Frameworks */ = { 75 | isa = PBXFrameworksBuildPhase; 76 | buildActionMask = 2147483647; 77 | files = ( 78 | B64A636A18AAB0990091A465 /* XCTest.framework in Frameworks */, 79 | B64A636C18AAB0990091A465 /* UIKit.framework in Frameworks */, 80 | B64A636B18AAB0990091A465 /* Foundation.framework in Frameworks */, 81 | ); 82 | runOnlyForDeploymentPostprocessing = 0; 83 | }; 84 | /* End PBXFrameworksBuildPhase section */ 85 | 86 | /* Begin PBXGroup section */ 87 | 79FD9B5A446B4FD6EEB36C5D /* Pods */ = { 88 | isa = PBXGroup; 89 | children = ( 90 | 220CB6253C40657765F007F6 /* Pods-VENCalculatorInputViewSample.debug.xcconfig */, 91 | C38F1368BB419BF5E1EC2072 /* Pods-VENCalculatorInputViewSample.release.xcconfig */, 92 | ); 93 | name = Pods; 94 | sourceTree = ""; 95 | }; 96 | B64A633E18AAB0990091A465 = { 97 | isa = PBXGroup; 98 | children = ( 99 | B64A635018AAB0990091A465 /* VENCalculatorInputViewSample */, 100 | B64A636F18AAB0990091A465 /* VENCalculatorInputViewSampleTests */, 101 | B64A634918AAB0990091A465 /* Frameworks */, 102 | B64A634818AAB0990091A465 /* Products */, 103 | 79FD9B5A446B4FD6EEB36C5D /* Pods */, 104 | ); 105 | sourceTree = ""; 106 | }; 107 | B64A634818AAB0990091A465 /* Products */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | B64A634718AAB0990091A465 /* VENCalculatorInputViewSample.app */, 111 | B64A636818AAB0990091A465 /* VENCalculatorInputViewSampleTests.xctest */, 112 | ); 113 | name = Products; 114 | sourceTree = ""; 115 | }; 116 | B64A634918AAB0990091A465 /* Frameworks */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | B64A634A18AAB0990091A465 /* Foundation.framework */, 120 | B64A634C18AAB0990091A465 /* CoreGraphics.framework */, 121 | B64A634E18AAB0990091A465 /* UIKit.framework */, 122 | B64A636918AAB0990091A465 /* XCTest.framework */, 123 | E99D08981FEF415990879498 /* libPods-VENCalculatorInputViewSample.a */, 124 | ); 125 | name = Frameworks; 126 | sourceTree = ""; 127 | }; 128 | B64A635018AAB0990091A465 /* VENCalculatorInputViewSample */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | B64A635918AAB0990091A465 /* VENAppDelegate.h */, 132 | B64A635A18AAB0990091A465 /* VENAppDelegate.m */, 133 | B64A635C18AAB0990091A465 /* Main.storyboard */, 134 | B64A635F18AAB0990091A465 /* VENViewController.h */, 135 | B64A636018AAB0990091A465 /* VENViewController.m */, 136 | B64A636218AAB0990091A465 /* Images.xcassets */, 137 | B64A635118AAB0990091A465 /* Supporting Files */, 138 | ); 139 | path = VENCalculatorInputViewSample; 140 | sourceTree = ""; 141 | }; 142 | B64A635118AAB0990091A465 /* Supporting Files */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | B64A635218AAB0990091A465 /* VENCalculatorInputViewSample-Info.plist */, 146 | B64A635318AAB0990091A465 /* InfoPlist.strings */, 147 | B64A635618AAB0990091A465 /* main.m */, 148 | B64A635818AAB0990091A465 /* VENCalculatorInputViewSample-Prefix.pch */, 149 | ); 150 | name = "Supporting Files"; 151 | sourceTree = ""; 152 | }; 153 | B64A636F18AAB0990091A465 /* VENCalculatorInputViewSampleTests */ = { 154 | isa = PBXGroup; 155 | children = ( 156 | B64A637518AAB09A0091A465 /* VENCalculatorInputViewSampleTests.m */, 157 | B64A637018AAB0990091A465 /* Supporting Files */, 158 | ); 159 | path = VENCalculatorInputViewSampleTests; 160 | sourceTree = ""; 161 | }; 162 | B64A637018AAB0990091A465 /* Supporting Files */ = { 163 | isa = PBXGroup; 164 | children = ( 165 | B64A637118AAB0990091A465 /* VENCalculatorInputViewSampleTests-Info.plist */, 166 | B64A637218AAB09A0091A465 /* InfoPlist.strings */, 167 | ); 168 | name = "Supporting Files"; 169 | sourceTree = ""; 170 | }; 171 | /* End PBXGroup section */ 172 | 173 | /* Begin PBXNativeTarget section */ 174 | B64A634618AAB0990091A465 /* VENCalculatorInputViewSample */ = { 175 | isa = PBXNativeTarget; 176 | buildConfigurationList = B64A637918AAB09A0091A465 /* Build configuration list for PBXNativeTarget "VENCalculatorInputViewSample" */; 177 | buildPhases = ( 178 | 2D2AA7AEAC7741FCB800E285 /* Check Pods Manifest.lock */, 179 | B64A634318AAB0990091A465 /* Sources */, 180 | B64A634418AAB0990091A465 /* Frameworks */, 181 | B64A634518AAB0990091A465 /* Resources */, 182 | 09EF00F391EA4C63878E7489 /* Copy Pods Resources */, 183 | ); 184 | buildRules = ( 185 | ); 186 | dependencies = ( 187 | ); 188 | name = VENCalculatorInputViewSample; 189 | productName = VENCalculatorInputViewSample; 190 | productReference = B64A634718AAB0990091A465 /* VENCalculatorInputViewSample.app */; 191 | productType = "com.apple.product-type.application"; 192 | }; 193 | B64A636718AAB0990091A465 /* VENCalculatorInputViewSampleTests */ = { 194 | isa = PBXNativeTarget; 195 | buildConfigurationList = B64A637C18AAB09A0091A465 /* Build configuration list for PBXNativeTarget "VENCalculatorInputViewSampleTests" */; 196 | buildPhases = ( 197 | B64A636418AAB0990091A465 /* Sources */, 198 | B64A636518AAB0990091A465 /* Frameworks */, 199 | B64A636618AAB0990091A465 /* Resources */, 200 | ); 201 | buildRules = ( 202 | ); 203 | dependencies = ( 204 | B64A636E18AAB0990091A465 /* PBXTargetDependency */, 205 | ); 206 | name = VENCalculatorInputViewSampleTests; 207 | productName = VENCalculatorInputViewSampleTests; 208 | productReference = B64A636818AAB0990091A465 /* VENCalculatorInputViewSampleTests.xctest */; 209 | productType = "com.apple.product-type.bundle.unit-test"; 210 | }; 211 | /* End PBXNativeTarget section */ 212 | 213 | /* Begin PBXProject section */ 214 | B64A633F18AAB0990091A465 /* Project object */ = { 215 | isa = PBXProject; 216 | attributes = { 217 | CLASSPREFIX = VEN; 218 | LastUpgradeCheck = 0500; 219 | ORGANIZATIONNAME = Venmo; 220 | TargetAttributes = { 221 | B64A636718AAB0990091A465 = { 222 | TestTargetID = B64A634618AAB0990091A465; 223 | }; 224 | }; 225 | }; 226 | buildConfigurationList = B64A634218AAB0990091A465 /* Build configuration list for PBXProject "VENCalculatorInputViewSample" */; 227 | compatibilityVersion = "Xcode 3.2"; 228 | developmentRegion = English; 229 | hasScannedForEncodings = 0; 230 | knownRegions = ( 231 | en, 232 | Base, 233 | ); 234 | mainGroup = B64A633E18AAB0990091A465; 235 | productRefGroup = B64A634818AAB0990091A465 /* Products */; 236 | projectDirPath = ""; 237 | projectRoot = ""; 238 | targets = ( 239 | B64A634618AAB0990091A465 /* VENCalculatorInputViewSample */, 240 | B64A636718AAB0990091A465 /* VENCalculatorInputViewSampleTests */, 241 | ); 242 | }; 243 | /* End PBXProject section */ 244 | 245 | /* Begin PBXResourcesBuildPhase section */ 246 | B64A634518AAB0990091A465 /* Resources */ = { 247 | isa = PBXResourcesBuildPhase; 248 | buildActionMask = 2147483647; 249 | files = ( 250 | B64A636318AAB0990091A465 /* Images.xcassets in Resources */, 251 | B64A635518AAB0990091A465 /* InfoPlist.strings in Resources */, 252 | B64A635E18AAB0990091A465 /* Main.storyboard in Resources */, 253 | ); 254 | runOnlyForDeploymentPostprocessing = 0; 255 | }; 256 | B64A636618AAB0990091A465 /* Resources */ = { 257 | isa = PBXResourcesBuildPhase; 258 | buildActionMask = 2147483647; 259 | files = ( 260 | B64A637418AAB09A0091A465 /* InfoPlist.strings in Resources */, 261 | ); 262 | runOnlyForDeploymentPostprocessing = 0; 263 | }; 264 | /* End PBXResourcesBuildPhase section */ 265 | 266 | /* Begin PBXShellScriptBuildPhase section */ 267 | 09EF00F391EA4C63878E7489 /* Copy Pods Resources */ = { 268 | isa = PBXShellScriptBuildPhase; 269 | buildActionMask = 2147483647; 270 | files = ( 271 | ); 272 | inputPaths = ( 273 | ); 274 | name = "Copy Pods Resources"; 275 | outputPaths = ( 276 | ); 277 | runOnlyForDeploymentPostprocessing = 0; 278 | shellPath = /bin/sh; 279 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-VENCalculatorInputViewSample/Pods-VENCalculatorInputViewSample-resources.sh\"\n"; 280 | showEnvVarsInLog = 0; 281 | }; 282 | 2D2AA7AEAC7741FCB800E285 /* Check Pods Manifest.lock */ = { 283 | isa = PBXShellScriptBuildPhase; 284 | buildActionMask = 2147483647; 285 | files = ( 286 | ); 287 | inputPaths = ( 288 | ); 289 | name = "Check Pods Manifest.lock"; 290 | outputPaths = ( 291 | ); 292 | runOnlyForDeploymentPostprocessing = 0; 293 | shellPath = /bin/sh; 294 | 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"; 295 | showEnvVarsInLog = 0; 296 | }; 297 | /* End PBXShellScriptBuildPhase section */ 298 | 299 | /* Begin PBXSourcesBuildPhase section */ 300 | B64A634318AAB0990091A465 /* Sources */ = { 301 | isa = PBXSourcesBuildPhase; 302 | buildActionMask = 2147483647; 303 | files = ( 304 | B64A636118AAB0990091A465 /* VENViewController.m in Sources */, 305 | B64A635B18AAB0990091A465 /* VENAppDelegate.m in Sources */, 306 | B64A635718AAB0990091A465 /* main.m in Sources */, 307 | ); 308 | runOnlyForDeploymentPostprocessing = 0; 309 | }; 310 | B64A636418AAB0990091A465 /* Sources */ = { 311 | isa = PBXSourcesBuildPhase; 312 | buildActionMask = 2147483647; 313 | files = ( 314 | B64A637618AAB09A0091A465 /* VENCalculatorInputViewSampleTests.m in Sources */, 315 | ); 316 | runOnlyForDeploymentPostprocessing = 0; 317 | }; 318 | /* End PBXSourcesBuildPhase section */ 319 | 320 | /* Begin PBXTargetDependency section */ 321 | B64A636E18AAB0990091A465 /* PBXTargetDependency */ = { 322 | isa = PBXTargetDependency; 323 | target = B64A634618AAB0990091A465 /* VENCalculatorInputViewSample */; 324 | targetProxy = B64A636D18AAB0990091A465 /* PBXContainerItemProxy */; 325 | }; 326 | /* End PBXTargetDependency section */ 327 | 328 | /* Begin PBXVariantGroup section */ 329 | B64A635318AAB0990091A465 /* InfoPlist.strings */ = { 330 | isa = PBXVariantGroup; 331 | children = ( 332 | B64A635418AAB0990091A465 /* en */, 333 | ); 334 | name = InfoPlist.strings; 335 | sourceTree = ""; 336 | }; 337 | B64A635C18AAB0990091A465 /* Main.storyboard */ = { 338 | isa = PBXVariantGroup; 339 | children = ( 340 | B64A635D18AAB0990091A465 /* Base */, 341 | ); 342 | name = Main.storyboard; 343 | sourceTree = ""; 344 | }; 345 | B64A637218AAB09A0091A465 /* InfoPlist.strings */ = { 346 | isa = PBXVariantGroup; 347 | children = ( 348 | B64A637318AAB09A0091A465 /* en */, 349 | ); 350 | name = InfoPlist.strings; 351 | sourceTree = ""; 352 | }; 353 | /* End PBXVariantGroup section */ 354 | 355 | /* Begin XCBuildConfiguration section */ 356 | B64A637718AAB09A0091A465 /* Debug */ = { 357 | isa = XCBuildConfiguration; 358 | buildSettings = { 359 | ALWAYS_SEARCH_USER_PATHS = NO; 360 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; 361 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 362 | CLANG_CXX_LIBRARY = "libc++"; 363 | CLANG_ENABLE_MODULES = YES; 364 | CLANG_ENABLE_OBJC_ARC = YES; 365 | CLANG_WARN_BOOL_CONVERSION = YES; 366 | CLANG_WARN_CONSTANT_CONVERSION = YES; 367 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 368 | CLANG_WARN_EMPTY_BODY = YES; 369 | CLANG_WARN_ENUM_CONVERSION = YES; 370 | CLANG_WARN_INT_CONVERSION = YES; 371 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 372 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 373 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 374 | COPY_PHASE_STRIP = NO; 375 | GCC_C_LANGUAGE_STANDARD = gnu99; 376 | GCC_DYNAMIC_NO_PIC = NO; 377 | GCC_OPTIMIZATION_LEVEL = 0; 378 | GCC_PREPROCESSOR_DEFINITIONS = ( 379 | "DEBUG=1", 380 | "$(inherited)", 381 | ); 382 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 383 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 384 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 385 | GCC_WARN_UNDECLARED_SELECTOR = YES; 386 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 387 | GCC_WARN_UNUSED_FUNCTION = YES; 388 | GCC_WARN_UNUSED_VARIABLE = YES; 389 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 390 | ONLY_ACTIVE_ARCH = YES; 391 | SDKROOT = iphoneos; 392 | }; 393 | name = Debug; 394 | }; 395 | B64A637818AAB09A0091A465 /* Release */ = { 396 | isa = XCBuildConfiguration; 397 | buildSettings = { 398 | ALWAYS_SEARCH_USER_PATHS = NO; 399 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; 400 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 401 | CLANG_CXX_LIBRARY = "libc++"; 402 | CLANG_ENABLE_MODULES = YES; 403 | CLANG_ENABLE_OBJC_ARC = YES; 404 | CLANG_WARN_BOOL_CONVERSION = YES; 405 | CLANG_WARN_CONSTANT_CONVERSION = YES; 406 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 407 | CLANG_WARN_EMPTY_BODY = YES; 408 | CLANG_WARN_ENUM_CONVERSION = YES; 409 | CLANG_WARN_INT_CONVERSION = YES; 410 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 411 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 412 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 413 | COPY_PHASE_STRIP = YES; 414 | ENABLE_NS_ASSERTIONS = NO; 415 | GCC_C_LANGUAGE_STANDARD = gnu99; 416 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 417 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 418 | GCC_WARN_UNDECLARED_SELECTOR = YES; 419 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 420 | GCC_WARN_UNUSED_FUNCTION = YES; 421 | GCC_WARN_UNUSED_VARIABLE = YES; 422 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 423 | SDKROOT = iphoneos; 424 | VALIDATE_PRODUCT = YES; 425 | }; 426 | name = Release; 427 | }; 428 | B64A637A18AAB09A0091A465 /* Debug */ = { 429 | isa = XCBuildConfiguration; 430 | baseConfigurationReference = 220CB6253C40657765F007F6 /* Pods-VENCalculatorInputViewSample.debug.xcconfig */; 431 | buildSettings = { 432 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 433 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 434 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 435 | GCC_PREFIX_HEADER = "VENCalculatorInputViewSample/VENCalculatorInputViewSample-Prefix.pch"; 436 | INFOPLIST_FILE = "VENCalculatorInputViewSample/VENCalculatorInputViewSample-Info.plist"; 437 | PRODUCT_NAME = "$(TARGET_NAME)"; 438 | WRAPPER_EXTENSION = app; 439 | }; 440 | name = Debug; 441 | }; 442 | B64A637B18AAB09A0091A465 /* Release */ = { 443 | isa = XCBuildConfiguration; 444 | baseConfigurationReference = C38F1368BB419BF5E1EC2072 /* Pods-VENCalculatorInputViewSample.release.xcconfig */; 445 | buildSettings = { 446 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 447 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 448 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 449 | GCC_PREFIX_HEADER = "VENCalculatorInputViewSample/VENCalculatorInputViewSample-Prefix.pch"; 450 | INFOPLIST_FILE = "VENCalculatorInputViewSample/VENCalculatorInputViewSample-Info.plist"; 451 | PRODUCT_NAME = "$(TARGET_NAME)"; 452 | WRAPPER_EXTENSION = app; 453 | }; 454 | name = Release; 455 | }; 456 | B64A637D18AAB09A0091A465 /* Debug */ = { 457 | isa = XCBuildConfiguration; 458 | buildSettings = { 459 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; 460 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/VENCalculatorInputViewSample.app/VENCalculatorInputViewSample"; 461 | FRAMEWORK_SEARCH_PATHS = ( 462 | "$(SDKROOT)/Developer/Library/Frameworks", 463 | "$(inherited)", 464 | "$(DEVELOPER_FRAMEWORKS_DIR)", 465 | ); 466 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 467 | GCC_PREFIX_HEADER = "VENCalculatorInputViewSample/VENCalculatorInputViewSample-Prefix.pch"; 468 | GCC_PREPROCESSOR_DEFINITIONS = ( 469 | "DEBUG=1", 470 | "$(inherited)", 471 | ); 472 | INFOPLIST_FILE = "VENCalculatorInputViewSampleTests/VENCalculatorInputViewSampleTests-Info.plist"; 473 | PRODUCT_NAME = "$(TARGET_NAME)"; 474 | TEST_HOST = "$(BUNDLE_LOADER)"; 475 | WRAPPER_EXTENSION = xctest; 476 | }; 477 | name = Debug; 478 | }; 479 | B64A637E18AAB09A0091A465 /* Release */ = { 480 | isa = XCBuildConfiguration; 481 | buildSettings = { 482 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; 483 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/VENCalculatorInputViewSample.app/VENCalculatorInputViewSample"; 484 | FRAMEWORK_SEARCH_PATHS = ( 485 | "$(SDKROOT)/Developer/Library/Frameworks", 486 | "$(inherited)", 487 | "$(DEVELOPER_FRAMEWORKS_DIR)", 488 | ); 489 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 490 | GCC_PREFIX_HEADER = "VENCalculatorInputViewSample/VENCalculatorInputViewSample-Prefix.pch"; 491 | INFOPLIST_FILE = "VENCalculatorInputViewSampleTests/VENCalculatorInputViewSampleTests-Info.plist"; 492 | PRODUCT_NAME = "$(TARGET_NAME)"; 493 | TEST_HOST = "$(BUNDLE_LOADER)"; 494 | WRAPPER_EXTENSION = xctest; 495 | }; 496 | name = Release; 497 | }; 498 | /* End XCBuildConfiguration section */ 499 | 500 | /* Begin XCConfigurationList section */ 501 | B64A634218AAB0990091A465 /* Build configuration list for PBXProject "VENCalculatorInputViewSample" */ = { 502 | isa = XCConfigurationList; 503 | buildConfigurations = ( 504 | B64A637718AAB09A0091A465 /* Debug */, 505 | B64A637818AAB09A0091A465 /* Release */, 506 | ); 507 | defaultConfigurationIsVisible = 0; 508 | defaultConfigurationName = Release; 509 | }; 510 | B64A637918AAB09A0091A465 /* Build configuration list for PBXNativeTarget "VENCalculatorInputViewSample" */ = { 511 | isa = XCConfigurationList; 512 | buildConfigurations = ( 513 | B64A637A18AAB09A0091A465 /* Debug */, 514 | B64A637B18AAB09A0091A465 /* Release */, 515 | ); 516 | defaultConfigurationIsVisible = 0; 517 | defaultConfigurationName = Release; 518 | }; 519 | B64A637C18AAB09A0091A465 /* Build configuration list for PBXNativeTarget "VENCalculatorInputViewSampleTests" */ = { 520 | isa = XCConfigurationList; 521 | buildConfigurations = ( 522 | B64A637D18AAB09A0091A465 /* Debug */, 523 | B64A637E18AAB09A0091A465 /* Release */, 524 | ); 525 | defaultConfigurationIsVisible = 0; 526 | defaultConfigurationName = Release; 527 | }; 528 | /* End XCConfigurationList section */ 529 | }; 530 | rootObject = B64A633F18AAB0990091A465 /* Project object */; 531 | } 532 | -------------------------------------------------------------------------------- /VENCalculatorInputViewSample/VENCalculatorInputViewSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /VENCalculatorInputViewSample/VENCalculatorInputViewSample.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /VENCalculatorInputViewSample/VENCalculatorInputViewSample/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /VENCalculatorInputViewSample/VENCalculatorInputViewSample/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" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /VENCalculatorInputViewSample/VENCalculatorInputViewSample/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /VENCalculatorInputViewSample/VENCalculatorInputViewSample/VENAppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface VENAppDelegate : UIResponder 4 | 5 | @property (strong, nonatomic) UIWindow *window; 6 | 7 | @end 8 | -------------------------------------------------------------------------------- /VENCalculatorInputViewSample/VENCalculatorInputViewSample/VENAppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "VENAppDelegate.h" 2 | 3 | @implementation VENAppDelegate 4 | 5 | @end 6 | -------------------------------------------------------------------------------- /VENCalculatorInputViewSample/VENCalculatorInputViewSample/VENCalculatorInputViewSample-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.venmo.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /VENCalculatorInputViewSample/VENCalculatorInputViewSample/VENCalculatorInputViewSample-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /VENCalculatorInputViewSample/VENCalculatorInputViewSample/VENViewController.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface VENViewController : UIViewController 4 | 5 | @end 6 | -------------------------------------------------------------------------------- /VENCalculatorInputViewSample/VENCalculatorInputViewSample/VENViewController.m: -------------------------------------------------------------------------------- 1 | #import "VENViewController.h" 2 | 3 | @interface VENViewController () 4 | 5 | @end 6 | 7 | @implementation VENViewController 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /VENCalculatorInputViewSample/VENCalculatorInputViewSample/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /VENCalculatorInputViewSample/VENCalculatorInputViewSample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // VENCalculatorInputViewSample 4 | // 5 | // Created by Ayaka Nonaka on 2/11/14. 6 | // Copyright (c) 2014 Venmo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "VENAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([VENAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /VENCalculatorInputViewSample/VENCalculatorInputViewSampleTests/VENCalculatorInputViewSampleTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.venmo.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /VENCalculatorInputViewSample/VENCalculatorInputViewSampleTests/VENCalculatorInputViewSampleTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // VENCalculatorInputViewSampleTests.m 3 | // VENCalculatorInputViewSampleTests 4 | // 5 | // Created by Ayaka Nonaka on 2/11/14. 6 | // Copyright (c) 2014 Venmo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface VENCalculatorInputViewSampleTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation VENCalculatorInputViewSampleTests 16 | 17 | - (void)setUp 18 | { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown 24 | { 25 | // Put teardown code here. This method is called after the invocation of each test method in the class. 26 | [super tearDown]; 27 | } 28 | 29 | - (void)testExample 30 | { 31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /VENCalculatorInputViewSample/VENCalculatorInputViewSampleTests/VENCalculatorSpecs.m: -------------------------------------------------------------------------------- 1 | #define EXP_SHORTHAND 2 | #import 3 | #import 4 | 5 | #import "VENCalculator.h" 6 | 7 | SpecBegin(VENCalculator) 8 | 9 | describe(@"Evaluate expressions", ^{ 10 | 11 | it(@"should handle addition", ^{ 12 | expect([VENCalculator evaluateExpression:@"1+1"]).to.equal(@"2"); 13 | expect([VENCalculator evaluateExpression:@"1 + 1"]).to.equal(@"2"); 14 | expect([VENCalculator evaluateExpression:@"1 + 1000"]).to.equal(@"1001"); 15 | }); 16 | 17 | it(@"should handle subtraction", ^{ 18 | expect([VENCalculator evaluateExpression:@"1-1"]).to.equal(@"0"); 19 | expect([VENCalculator evaluateExpression:@"10000-1"]).to.equal(@"9999"); 20 | expect([VENCalculator evaluateExpression:@"0 - 100"]).to.equal(@"-100"); 21 | }); 22 | 23 | it(@"should handle multiplication", ^{ 24 | expect([VENCalculator evaluateExpression:@"2*2"]).to.equal(@"4"); 25 | expect([VENCalculator evaluateExpression:@"100*1.2"]).to.equal(@"120"); 26 | expect([VENCalculator evaluateExpression:@"1000 * 0.8"]).to.equal(@"800"); 27 | }); 28 | 29 | it(@"should handle division", ^{ 30 | expect([VENCalculator evaluateExpression:@"2/2"]).to.equal(@"1"); 31 | expect([VENCalculator evaluateExpression:@"100/4"]).to.equal(@"25"); 32 | expect([VENCalculator evaluateExpression:@"1/2"]).to.equal(@"0.50"); 33 | }); 34 | 35 | it(@"should return nil for invalid expressions", ^{ 36 | expect([VENCalculator evaluateExpression:@"1+++1"]).to.beNil(); 37 | expect([VENCalculator evaluateExpression:@"++++-12!@#"]).to.beNil(); 38 | expect([VENCalculator evaluateExpression:@"+"]).to.beNil(); 39 | expect([VENCalculator evaluateExpression:@"1+"]).to.beNil(); 40 | }); 41 | 42 | }); 43 | 44 | SpecEnd 45 | -------------------------------------------------------------------------------- /VENCalculatorInputViewSample/VENCalculatorInputViewSampleTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /VENCalculatorInputViewTests/NSString+VENCalculatorInputViewSpec.m: -------------------------------------------------------------------------------- 1 | #define EXP_SHORTHAND 2 | #import 3 | #import 4 | 5 | #import "NSString+VENCalculatorInputView.h" 6 | 7 | SpecBegin(NSString_VENCalculatorInputView) 8 | 9 | describe(@"stringByReplacingCharactersInSet:withString:", ^{ 10 | 11 | it(@"should handle whitespace characters", ^{ 12 | NSString *s = @"foo bar\n "; 13 | NSString *result = [s stringByReplacingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] withString:@""]; 14 | expect(result).to.equal(@"foobar"); 15 | }); 16 | 17 | it(@"should handle custom NSCharacterSet", ^{ 18 | NSString *s = @"1+1(&^!@#+1foobar"; 19 | NSCharacterSet *characterSet = [[NSCharacterSet characterSetWithCharactersInString:@"0123456789-/*.+"] invertedSet]; 20 | NSString *result = [s stringByReplacingCharactersInSet:characterSet withString:@""]; 21 | expect(result).to.equal(@"1+1+1"); 22 | }); 23 | }); 24 | 25 | SpecEnd -------------------------------------------------------------------------------- /VENCalculatorInputViewTests/UITextField+VENCalculatorInputViewSpec.m: -------------------------------------------------------------------------------- 1 | #define EXP_SHORTHAND 2 | #import 3 | #import 4 | #import 5 | 6 | #import "UITextField+VENCalculatorInputView.h" 7 | 8 | SpecBegin(UITextRange_VENCalculatorInputView) 9 | 10 | describe(@"selectedNSRange", ^{ 11 | 12 | it(@"should get UITextField's selectedText in an NSRange", ^{ 13 | id mockBeginningTextPosition = OCMClassMock([UITextPosition class]); 14 | id mockSelectionStartTextPosition = OCMClassMock([UITextPosition class]); 15 | id mockSelectionEndTextPosition = OCMClassMock([UITextPosition class]); 16 | 17 | id mockTextField = OCMClassMock([UITextField class]); 18 | id mockSelectedTextRange = OCMClassMock([UITextRange class]); 19 | 20 | OCMStub([mockTextField beginningOfDocument]).andReturn(mockBeginningTextPosition); 21 | OCMStub([mockTextField selectedTextRange]).andReturn(mockSelectedTextRange); 22 | OCMStub([(UITextRange *)mockSelectedTextRange start]).andReturn(mockSelectionStartTextPosition); 23 | OCMStub([(UITextRange *)mockSelectedTextRange end]).andReturn(mockSelectionEndTextPosition); 24 | 25 | [[mockTextField expect] offsetFromPosition:mockBeginningTextPosition toPosition:mockSelectionStartTextPosition]; 26 | [[mockTextField expect] offsetFromPosition:mockSelectionStartTextPosition toPosition:mockSelectionEndTextPosition]; 27 | 28 | [mockTextField selectedNSRange]; 29 | }); 30 | }); 31 | 32 | SpecEnd 33 | -------------------------------------------------------------------------------- /VENCalculatorInputViewTests/VENCalculatorInputViewTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.venmo.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /VENCalculatorInputViewTests/VENMoneyCalculatorSpec.m: -------------------------------------------------------------------------------- 1 | #define EXP_SHORTHAND 2 | #import 3 | #import 4 | #import 5 | 6 | #import "VENMoneyCalculator.h" 7 | 8 | SpecBegin(VENMoneyCalculator) 9 | 10 | describe(@"Evaluate expressions", ^{ 11 | __block VENMoneyCalculator *moneyCalculator; 12 | 13 | beforeAll(^{ 14 | moneyCalculator = [VENMoneyCalculator new]; 15 | moneyCalculator.locale = [NSLocale localeWithLocaleIdentifier:@"en_US"]; 16 | }); 17 | 18 | it(@"should handle addition", ^{ 19 | expect([moneyCalculator evaluateExpression:@"1+1"]).to.equal(@"2"); 20 | expect([moneyCalculator evaluateExpression:@"1 + 1"]).to.equal(@"2"); 21 | expect([moneyCalculator evaluateExpression:@"1 + 1000"]).to.equal(@"1001"); 22 | }); 23 | 24 | it(@"should handle subtraction", ^{ 25 | expect([moneyCalculator evaluateExpression:@"1-1"]).to.equal(@"0"); 26 | expect([moneyCalculator evaluateExpression:@"10000-1"]).to.equal(@"9999"); 27 | expect([moneyCalculator evaluateExpression:@"0 - 100"]).to.equal(@"-100"); 28 | }); 29 | 30 | it(@"should handle multiplication", ^{ 31 | expect([moneyCalculator evaluateExpression:@"2*2"]).to.equal(@"4"); 32 | expect([moneyCalculator evaluateExpression:@"100*1.2"]).to.equal(@"120"); 33 | expect([moneyCalculator evaluateExpression:@"1000 * 0.8"]).to.equal(@"800"); 34 | }); 35 | 36 | it(@"should handle division", ^{ 37 | expect([moneyCalculator evaluateExpression:@"2/2"]).to.equal(@"1"); 38 | expect([moneyCalculator evaluateExpression:@"100/4"]).to.equal(@"25"); 39 | expect([moneyCalculator evaluateExpression:@"1/2"]).to.equal(@"0.50"); 40 | }); 41 | 42 | it(@"should return nil for invalid expressions", ^{ 43 | expect([moneyCalculator evaluateExpression:@"1+++1"]).to.beNil(); 44 | expect([moneyCalculator evaluateExpression:@"++++-12!@#"]).to.beNil(); 45 | expect([moneyCalculator evaluateExpression:@"+"]).to.beNil(); 46 | expect([moneyCalculator evaluateExpression:@"1+"]).to.beNil(); 47 | }); 48 | 49 | it(@"should handle − (longer dash)", ^{ 50 | expect([moneyCalculator evaluateExpression:@"1−1"]).to.equal(@"0"); 51 | expect([moneyCalculator evaluateExpression:@"10000−1"]).to.equal(@"9999"); 52 | expect([moneyCalculator evaluateExpression:@"0 − 100"]).to.equal(@"-100"); 53 | }); 54 | 55 | it(@"should handle ×", ^{ 56 | expect([moneyCalculator evaluateExpression:@"2×2"]).to.equal(@"4"); 57 | expect([moneyCalculator evaluateExpression:@"100×1.2"]).to.equal(@"120"); 58 | expect([moneyCalculator evaluateExpression:@"1000 × 0.8"]).to.equal(@"800"); 59 | }); 60 | 61 | it(@"should handle ÷", ^{ 62 | expect([moneyCalculator evaluateExpression:@"2÷2"]).to.equal(@"1"); 63 | expect([moneyCalculator evaluateExpression:@"100÷4"]).to.equal(@"25"); 64 | expect([moneyCalculator evaluateExpression:@"1÷2"]).to.equal(@"0.50"); 65 | }); 66 | 67 | it(@"should handle ÷ 0", ^{ 68 | expect([moneyCalculator evaluateExpression:@"2÷0"]).to.equal(@"0"); 69 | expect([moneyCalculator evaluateExpression:@"0÷0"]).to.equal(@"0"); 70 | expect([moneyCalculator evaluateExpression:@"-2÷0"]).to.equal(@"0"); 71 | expect([moneyCalculator evaluateExpression:@"-0÷0"]).to.equal(@"0"); 72 | }); 73 | 74 | }); 75 | 76 | 77 | describe(@"Handle other locale", ^{ 78 | __block VENMoneyCalculator *moneyCalculator; 79 | 80 | beforeAll(^{ 81 | moneyCalculator = [VENMoneyCalculator new]; 82 | moneyCalculator.locale = [NSLocale localeWithLocaleIdentifier:@"fr_FR"]; 83 | }); 84 | 85 | it(@"should handle division", ^{ 86 | expect([moneyCalculator evaluateExpression:@"2/2"]).to.equal(@"1"); 87 | expect([moneyCalculator evaluateExpression:@"100/4"]).to.equal(@"25"); 88 | expect([moneyCalculator evaluateExpression:@"1/2"]).to.equal(@"0,50"); 89 | }); 90 | 91 | it(@"should handle ×", ^{ 92 | expect([moneyCalculator evaluateExpression:@"100×1,2"]).to.equal(@"120"); 93 | expect([moneyCalculator evaluateExpression:@"1000 × 0,8"]).to.equal(@"800"); 94 | }); 95 | 96 | }); 97 | 98 | describe(@"Handle Deutsch, which use . as grouping seperator", ^{ 99 | __block VENMoneyCalculator *moneyCalculator; 100 | 101 | beforeAll(^{ 102 | moneyCalculator = [VENMoneyCalculator new]; 103 | moneyCalculator.locale = [NSLocale localeWithLocaleIdentifier:@"de_DE"]; 104 | }); 105 | 106 | it(@"should handle division", ^{ 107 | expect([moneyCalculator evaluateExpression:@"2/2"]).to.equal(@"1"); 108 | expect([moneyCalculator evaluateExpression:@"100/4"]).to.equal(@"25"); 109 | expect([moneyCalculator evaluateExpression:@"1/2"]).to.equal(@"0,50"); 110 | }); 111 | 112 | it(@"should handle ×", ^{ 113 | expect([moneyCalculator evaluateExpression:@"100×1,2"]).to.equal(@"120"); 114 | expect([moneyCalculator evaluateExpression:@"1000 × 0,8"]).to.equal(@"800"); 115 | }); 116 | 117 | it(@"should handle big numbers", ^{ 118 | expect([moneyCalculator evaluateExpression:@"1.035,01+40"]).to.equal(@"1.075,01"); 119 | expect([moneyCalculator evaluateExpression:@"1.040,01-1.035"]).to.equal(@"5,01"); 120 | }); 121 | 122 | }); 123 | 124 | describe(@"locale", ^{ 125 | __block VENMoneyCalculator *moneyCalculator; 126 | __block id mockLocale; 127 | 128 | beforeAll(^{ 129 | mockLocale = [OCMockObject mockForClass:[NSLocale class]]; 130 | [[[mockLocale stub] andReturn:[NSLocale localeWithLocaleIdentifier:@"vi_VN"]] currentLocale]; 131 | moneyCalculator = [VENMoneyCalculator new]; 132 | }); 133 | 134 | afterAll(^{ 135 | [mockLocale stopMocking]; 136 | }); 137 | 138 | it(@"should use the current locale by default (Vietname in this case)", ^{ 139 | expect([moneyCalculator evaluateExpression:@"1,90"]).to.equal(@"2"); 140 | expect([moneyCalculator evaluateExpression:@"1,30"]).to.equal(@"1"); 141 | expect([moneyCalculator evaluateExpression:@"0,90"]).to.equal(@"1"); 142 | }); 143 | 144 | it(@"should use the specified locale if set", ^{ 145 | moneyCalculator.locale = [NSLocale localeWithLocaleIdentifier:@"en_US"]; 146 | expect([moneyCalculator evaluateExpression:@"1.9"]).to.equal(@"1.90"); 147 | expect([moneyCalculator evaluateExpression:@"1.30"]).to.equal(@"1.30"); 148 | expect([moneyCalculator evaluateExpression:@"0.90"]).to.equal(@"0.90"); 149 | }); 150 | }); 151 | 152 | SpecEnd -------------------------------------------------------------------------------- /VENCalculatorInputViewTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | --------------------------------------------------------------------------------