├── InputHelper.podspec ├── InputHelper.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── InputHelper.xccheckout │ └── xcuserdata │ │ └── Mac.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── Mac.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── InputHelper.xcscheme │ └── xcschememanagement.plist ├── InputHelper ├── AppDelegate.h ├── AppDelegate.m ├── Base.lproj │ └── LaunchScreen.xib ├── Images.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── LaunchImage.launchimage │ │ └── Contents.json ├── Images │ ├── btn_bg_round_green_290x80.png │ ├── input_box_600x80.png │ └── input_box_602x203.png ├── Info.plist ├── InputHelper │ ├── InputHelper.h │ └── InputHelper.m ├── TestControllers │ ├── BaseViewController.h │ ├── BaseViewController.m │ ├── UIScrollViewTest_ViewController.h │ ├── UIScrollViewTest_ViewController.m │ ├── UIScrollViewTest_ViewController.xib │ ├── UIViewTest_ViewController.h │ ├── UIViewTest_ViewController.m │ └── UIViewTest_ViewController.xib ├── ViewController.h ├── ViewController.m ├── ViewController.xib └── main.m ├── InputHelperTests ├── Info.plist └── InputHelperTests.m ├── LICENSE ├── README.md └── _config.yml /InputHelper.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint InputHelper.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | 11 | s.name = "InputHelper" 12 | s.version = "0.0.1" 13 | s.summary = "InputHelper can auto adjust the frame of UITextField,UTextView and UISearchBar" 14 | s.homepage = "https://github.com/masong2012/InputHelper" 15 | s.license = "MIT" 16 | s.author = { "masong" => "bcdvip@gmail.com" } 17 | s.platform = :ios, "5.0" 18 | s.source = { :git => "https://github.com/masong2012/InputHelper.git", :tag => "0.0.1" } 19 | s.source_files = "InputHelper/*" 20 | s.frameworks = "Foundation", "UIKit" 21 | s.requires_arc = true 22 | 23 | end 24 | -------------------------------------------------------------------------------- /InputHelper.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 04246D2B1A5D90CD005AD629 /* input_box_600x80.png in Resources */ = {isa = PBXBuildFile; fileRef = 04246D291A5D90CD005AD629 /* input_box_600x80.png */; }; 11 | 04246D2C1A5D90CD005AD629 /* input_box_602x203.png in Resources */ = {isa = PBXBuildFile; fileRef = 04246D2A1A5D90CD005AD629 /* input_box_602x203.png */; }; 12 | 04246D2E1A5D91D5005AD629 /* btn_bg_round_green_290x80.png in Resources */ = {isa = PBXBuildFile; fileRef = 04246D2D1A5D91D5005AD629 /* btn_bg_round_green_290x80.png */; }; 13 | 04246D331A5D9601005AD629 /* UIViewTest_ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 04246D311A5D9601005AD629 /* UIViewTest_ViewController.m */; }; 14 | 04246D341A5D9601005AD629 /* UIViewTest_ViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 04246D321A5D9601005AD629 /* UIViewTest_ViewController.xib */; }; 15 | 04246D381A5D9627005AD629 /* UIScrollViewTest_ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 04246D361A5D9627005AD629 /* UIScrollViewTest_ViewController.m */; }; 16 | 04246D391A5D9627005AD629 /* UIScrollViewTest_ViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 04246D371A5D9627005AD629 /* UIScrollViewTest_ViewController.xib */; }; 17 | 04246D451A5D985F005AD629 /* ViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 04246D441A5D985F005AD629 /* ViewController.xib */; }; 18 | 044699891A028F7400C4E6F1 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 044699881A028F7400C4E6F1 /* main.m */; }; 19 | 0446998C1A028F7400C4E6F1 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 0446998B1A028F7400C4E6F1 /* AppDelegate.m */; }; 20 | 0446998F1A028F7400C4E6F1 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0446998E1A028F7400C4E6F1 /* ViewController.m */; }; 21 | 044699941A028F7400C4E6F1 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 044699931A028F7400C4E6F1 /* Images.xcassets */; }; 22 | 044699971A028F7400C4E6F1 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 044699951A028F7400C4E6F1 /* LaunchScreen.xib */; }; 23 | 044699A31A028F7400C4E6F1 /* InputHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 044699A21A028F7400C4E6F1 /* InputHelperTests.m */; }; 24 | 0459D0031A41387400F01F73 /* InputHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 0459D0021A41387400F01F73 /* InputHelper.m */; }; 25 | 048759B11A62BD350065FD2E /* BaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 048759B01A62BD350065FD2E /* BaseViewController.m */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXContainerItemProxy section */ 29 | 0446999D1A028F7400C4E6F1 /* PBXContainerItemProxy */ = { 30 | isa = PBXContainerItemProxy; 31 | containerPortal = 0446997B1A028F7400C4E6F1 /* Project object */; 32 | proxyType = 1; 33 | remoteGlobalIDString = 044699821A028F7400C4E6F1; 34 | remoteInfo = InputHelper; 35 | }; 36 | /* End PBXContainerItemProxy section */ 37 | 38 | /* Begin PBXFileReference section */ 39 | 04246D291A5D90CD005AD629 /* input_box_600x80.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = input_box_600x80.png; sourceTree = ""; }; 40 | 04246D2A1A5D90CD005AD629 /* input_box_602x203.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = input_box_602x203.png; sourceTree = ""; }; 41 | 04246D2D1A5D91D5005AD629 /* btn_bg_round_green_290x80.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = btn_bg_round_green_290x80.png; sourceTree = ""; }; 42 | 04246D301A5D9601005AD629 /* UIViewTest_ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UIViewTest_ViewController.h; path = TestControllers/UIViewTest_ViewController.h; sourceTree = ""; }; 43 | 04246D311A5D9601005AD629 /* UIViewTest_ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = UIViewTest_ViewController.m; path = TestControllers/UIViewTest_ViewController.m; sourceTree = ""; }; 44 | 04246D321A5D9601005AD629 /* UIViewTest_ViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = UIViewTest_ViewController.xib; path = TestControllers/UIViewTest_ViewController.xib; sourceTree = ""; }; 45 | 04246D351A5D9627005AD629 /* UIScrollViewTest_ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UIScrollViewTest_ViewController.h; path = TestControllers/UIScrollViewTest_ViewController.h; sourceTree = ""; }; 46 | 04246D361A5D9627005AD629 /* UIScrollViewTest_ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = UIScrollViewTest_ViewController.m; path = TestControllers/UIScrollViewTest_ViewController.m; sourceTree = ""; }; 47 | 04246D371A5D9627005AD629 /* UIScrollViewTest_ViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = UIScrollViewTest_ViewController.xib; path = TestControllers/UIScrollViewTest_ViewController.xib; sourceTree = ""; }; 48 | 04246D441A5D985F005AD629 /* ViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ViewController.xib; sourceTree = ""; }; 49 | 044699831A028F7400C4E6F1 /* InputHelper.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = InputHelper.app; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | 044699871A028F7400C4E6F1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 51 | 044699881A028F7400C4E6F1 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 52 | 0446998A1A028F7400C4E6F1 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 53 | 0446998B1A028F7400C4E6F1 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 54 | 0446998D1A028F7400C4E6F1 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 55 | 0446998E1A028F7400C4E6F1 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 56 | 044699931A028F7400C4E6F1 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 57 | 044699961A028F7400C4E6F1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 58 | 0446999C1A028F7400C4E6F1 /* InputHelperTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InputHelperTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 59 | 044699A11A028F7400C4E6F1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 60 | 044699A21A028F7400C4E6F1 /* InputHelperTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InputHelperTests.m; sourceTree = ""; }; 61 | 0459D0011A41387400F01F73 /* InputHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InputHelper.h; sourceTree = ""; }; 62 | 0459D0021A41387400F01F73 /* InputHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InputHelper.m; sourceTree = ""; }; 63 | 048759AF1A62BD350065FD2E /* BaseViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BaseViewController.h; path = TestControllers/BaseViewController.h; sourceTree = ""; }; 64 | 048759B01A62BD350065FD2E /* BaseViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BaseViewController.m; path = TestControllers/BaseViewController.m; sourceTree = ""; }; 65 | /* End PBXFileReference section */ 66 | 67 | /* Begin PBXFrameworksBuildPhase section */ 68 | 044699801A028F7400C4E6F1 /* Frameworks */ = { 69 | isa = PBXFrameworksBuildPhase; 70 | buildActionMask = 2147483647; 71 | files = ( 72 | ); 73 | runOnlyForDeploymentPostprocessing = 0; 74 | }; 75 | 044699991A028F7400C4E6F1 /* Frameworks */ = { 76 | isa = PBXFrameworksBuildPhase; 77 | buildActionMask = 2147483647; 78 | files = ( 79 | ); 80 | runOnlyForDeploymentPostprocessing = 0; 81 | }; 82 | /* End PBXFrameworksBuildPhase section */ 83 | 84 | /* Begin PBXGroup section */ 85 | 04246D281A5D90CD005AD629 /* Images */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | 04246D2D1A5D91D5005AD629 /* btn_bg_round_green_290x80.png */, 89 | 04246D291A5D90CD005AD629 /* input_box_600x80.png */, 90 | 04246D2A1A5D90CD005AD629 /* input_box_602x203.png */, 91 | ); 92 | path = Images; 93 | sourceTree = ""; 94 | }; 95 | 04246D2F1A5D95AA005AD629 /* TestControllers */ = { 96 | isa = PBXGroup; 97 | children = ( 98 | 04246D301A5D9601005AD629 /* UIViewTest_ViewController.h */, 99 | 04246D311A5D9601005AD629 /* UIViewTest_ViewController.m */, 100 | 04246D321A5D9601005AD629 /* UIViewTest_ViewController.xib */, 101 | 04246D351A5D9627005AD629 /* UIScrollViewTest_ViewController.h */, 102 | 04246D361A5D9627005AD629 /* UIScrollViewTest_ViewController.m */, 103 | 04246D371A5D9627005AD629 /* UIScrollViewTest_ViewController.xib */, 104 | 048759AF1A62BD350065FD2E /* BaseViewController.h */, 105 | 048759B01A62BD350065FD2E /* BaseViewController.m */, 106 | ); 107 | name = TestControllers; 108 | sourceTree = ""; 109 | }; 110 | 0446997A1A028F7400C4E6F1 = { 111 | isa = PBXGroup; 112 | children = ( 113 | 044699851A028F7400C4E6F1 /* InputHelper */, 114 | 0446999F1A028F7400C4E6F1 /* InputHelperTests */, 115 | 044699841A028F7400C4E6F1 /* Products */, 116 | ); 117 | sourceTree = ""; 118 | }; 119 | 044699841A028F7400C4E6F1 /* Products */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | 044699831A028F7400C4E6F1 /* InputHelper.app */, 123 | 0446999C1A028F7400C4E6F1 /* InputHelperTests.xctest */, 124 | ); 125 | name = Products; 126 | sourceTree = ""; 127 | }; 128 | 044699851A028F7400C4E6F1 /* InputHelper */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | 04246D2F1A5D95AA005AD629 /* TestControllers */, 132 | 04246D281A5D90CD005AD629 /* Images */, 133 | 0459D0001A41387400F01F73 /* InputHelper */, 134 | 0446998A1A028F7400C4E6F1 /* AppDelegate.h */, 135 | 0446998B1A028F7400C4E6F1 /* AppDelegate.m */, 136 | 0446998D1A028F7400C4E6F1 /* ViewController.h */, 137 | 0446998E1A028F7400C4E6F1 /* ViewController.m */, 138 | 04246D441A5D985F005AD629 /* ViewController.xib */, 139 | 044699931A028F7400C4E6F1 /* Images.xcassets */, 140 | 044699951A028F7400C4E6F1 /* LaunchScreen.xib */, 141 | 044699861A028F7400C4E6F1 /* Supporting Files */, 142 | ); 143 | path = InputHelper; 144 | sourceTree = ""; 145 | }; 146 | 044699861A028F7400C4E6F1 /* Supporting Files */ = { 147 | isa = PBXGroup; 148 | children = ( 149 | 044699871A028F7400C4E6F1 /* Info.plist */, 150 | 044699881A028F7400C4E6F1 /* main.m */, 151 | ); 152 | name = "Supporting Files"; 153 | sourceTree = ""; 154 | }; 155 | 0446999F1A028F7400C4E6F1 /* InputHelperTests */ = { 156 | isa = PBXGroup; 157 | children = ( 158 | 044699A21A028F7400C4E6F1 /* InputHelperTests.m */, 159 | 044699A01A028F7400C4E6F1 /* Supporting Files */, 160 | ); 161 | path = InputHelperTests; 162 | sourceTree = ""; 163 | }; 164 | 044699A01A028F7400C4E6F1 /* Supporting Files */ = { 165 | isa = PBXGroup; 166 | children = ( 167 | 044699A11A028F7400C4E6F1 /* Info.plist */, 168 | ); 169 | name = "Supporting Files"; 170 | sourceTree = ""; 171 | }; 172 | 0459D0001A41387400F01F73 /* InputHelper */ = { 173 | isa = PBXGroup; 174 | children = ( 175 | 0459D0011A41387400F01F73 /* InputHelper.h */, 176 | 0459D0021A41387400F01F73 /* InputHelper.m */, 177 | ); 178 | path = InputHelper; 179 | sourceTree = ""; 180 | }; 181 | /* End PBXGroup section */ 182 | 183 | /* Begin PBXNativeTarget section */ 184 | 044699821A028F7400C4E6F1 /* InputHelper */ = { 185 | isa = PBXNativeTarget; 186 | buildConfigurationList = 044699A61A028F7400C4E6F1 /* Build configuration list for PBXNativeTarget "InputHelper" */; 187 | buildPhases = ( 188 | 0446997F1A028F7400C4E6F1 /* Sources */, 189 | 044699801A028F7400C4E6F1 /* Frameworks */, 190 | 044699811A028F7400C4E6F1 /* Resources */, 191 | ); 192 | buildRules = ( 193 | ); 194 | dependencies = ( 195 | ); 196 | name = InputHelper; 197 | productName = InputHelper; 198 | productReference = 044699831A028F7400C4E6F1 /* InputHelper.app */; 199 | productType = "com.apple.product-type.application"; 200 | }; 201 | 0446999B1A028F7400C4E6F1 /* InputHelperTests */ = { 202 | isa = PBXNativeTarget; 203 | buildConfigurationList = 044699A91A028F7400C4E6F1 /* Build configuration list for PBXNativeTarget "InputHelperTests" */; 204 | buildPhases = ( 205 | 044699981A028F7400C4E6F1 /* Sources */, 206 | 044699991A028F7400C4E6F1 /* Frameworks */, 207 | 0446999A1A028F7400C4E6F1 /* Resources */, 208 | ); 209 | buildRules = ( 210 | ); 211 | dependencies = ( 212 | 0446999E1A028F7400C4E6F1 /* PBXTargetDependency */, 213 | ); 214 | name = InputHelperTests; 215 | productName = InputHelperTests; 216 | productReference = 0446999C1A028F7400C4E6F1 /* InputHelperTests.xctest */; 217 | productType = "com.apple.product-type.bundle.unit-test"; 218 | }; 219 | /* End PBXNativeTarget section */ 220 | 221 | /* Begin PBXProject section */ 222 | 0446997B1A028F7400C4E6F1 /* Project object */ = { 223 | isa = PBXProject; 224 | attributes = { 225 | LastUpgradeCheck = 0610; 226 | ORGANIZATIONNAME = MaSong; 227 | TargetAttributes = { 228 | 044699821A028F7400C4E6F1 = { 229 | CreatedOnToolsVersion = 6.1; 230 | }; 231 | 0446999B1A028F7400C4E6F1 = { 232 | CreatedOnToolsVersion = 6.1; 233 | TestTargetID = 044699821A028F7400C4E6F1; 234 | }; 235 | }; 236 | }; 237 | buildConfigurationList = 0446997E1A028F7400C4E6F1 /* Build configuration list for PBXProject "InputHelper" */; 238 | compatibilityVersion = "Xcode 3.2"; 239 | developmentRegion = English; 240 | hasScannedForEncodings = 0; 241 | knownRegions = ( 242 | en, 243 | Base, 244 | ); 245 | mainGroup = 0446997A1A028F7400C4E6F1; 246 | productRefGroup = 044699841A028F7400C4E6F1 /* Products */; 247 | projectDirPath = ""; 248 | projectRoot = ""; 249 | targets = ( 250 | 044699821A028F7400C4E6F1 /* InputHelper */, 251 | 0446999B1A028F7400C4E6F1 /* InputHelperTests */, 252 | ); 253 | }; 254 | /* End PBXProject section */ 255 | 256 | /* Begin PBXResourcesBuildPhase section */ 257 | 044699811A028F7400C4E6F1 /* Resources */ = { 258 | isa = PBXResourcesBuildPhase; 259 | buildActionMask = 2147483647; 260 | files = ( 261 | 04246D451A5D985F005AD629 /* ViewController.xib in Resources */, 262 | 04246D2B1A5D90CD005AD629 /* input_box_600x80.png in Resources */, 263 | 04246D341A5D9601005AD629 /* UIViewTest_ViewController.xib in Resources */, 264 | 04246D391A5D9627005AD629 /* UIScrollViewTest_ViewController.xib in Resources */, 265 | 04246D2C1A5D90CD005AD629 /* input_box_602x203.png in Resources */, 266 | 044699971A028F7400C4E6F1 /* LaunchScreen.xib in Resources */, 267 | 044699941A028F7400C4E6F1 /* Images.xcassets in Resources */, 268 | 04246D2E1A5D91D5005AD629 /* btn_bg_round_green_290x80.png in Resources */, 269 | ); 270 | runOnlyForDeploymentPostprocessing = 0; 271 | }; 272 | 0446999A1A028F7400C4E6F1 /* Resources */ = { 273 | isa = PBXResourcesBuildPhase; 274 | buildActionMask = 2147483647; 275 | files = ( 276 | ); 277 | runOnlyForDeploymentPostprocessing = 0; 278 | }; 279 | /* End PBXResourcesBuildPhase section */ 280 | 281 | /* Begin PBXSourcesBuildPhase section */ 282 | 0446997F1A028F7400C4E6F1 /* Sources */ = { 283 | isa = PBXSourcesBuildPhase; 284 | buildActionMask = 2147483647; 285 | files = ( 286 | 0459D0031A41387400F01F73 /* InputHelper.m in Sources */, 287 | 048759B11A62BD350065FD2E /* BaseViewController.m in Sources */, 288 | 0446998F1A028F7400C4E6F1 /* ViewController.m in Sources */, 289 | 0446998C1A028F7400C4E6F1 /* AppDelegate.m in Sources */, 290 | 044699891A028F7400C4E6F1 /* main.m in Sources */, 291 | 04246D381A5D9627005AD629 /* UIScrollViewTest_ViewController.m in Sources */, 292 | 04246D331A5D9601005AD629 /* UIViewTest_ViewController.m in Sources */, 293 | ); 294 | runOnlyForDeploymentPostprocessing = 0; 295 | }; 296 | 044699981A028F7400C4E6F1 /* Sources */ = { 297 | isa = PBXSourcesBuildPhase; 298 | buildActionMask = 2147483647; 299 | files = ( 300 | 044699A31A028F7400C4E6F1 /* InputHelperTests.m in Sources */, 301 | ); 302 | runOnlyForDeploymentPostprocessing = 0; 303 | }; 304 | /* End PBXSourcesBuildPhase section */ 305 | 306 | /* Begin PBXTargetDependency section */ 307 | 0446999E1A028F7400C4E6F1 /* PBXTargetDependency */ = { 308 | isa = PBXTargetDependency; 309 | target = 044699821A028F7400C4E6F1 /* InputHelper */; 310 | targetProxy = 0446999D1A028F7400C4E6F1 /* PBXContainerItemProxy */; 311 | }; 312 | /* End PBXTargetDependency section */ 313 | 314 | /* Begin PBXVariantGroup section */ 315 | 044699951A028F7400C4E6F1 /* LaunchScreen.xib */ = { 316 | isa = PBXVariantGroup; 317 | children = ( 318 | 044699961A028F7400C4E6F1 /* Base */, 319 | ); 320 | name = LaunchScreen.xib; 321 | sourceTree = ""; 322 | }; 323 | /* End PBXVariantGroup section */ 324 | 325 | /* Begin XCBuildConfiguration section */ 326 | 044699A41A028F7400C4E6F1 /* Debug */ = { 327 | isa = XCBuildConfiguration; 328 | buildSettings = { 329 | ALWAYS_SEARCH_USER_PATHS = NO; 330 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 331 | CLANG_CXX_LIBRARY = "libc++"; 332 | CLANG_ENABLE_MODULES = YES; 333 | CLANG_ENABLE_OBJC_ARC = YES; 334 | CLANG_WARN_BOOL_CONVERSION = YES; 335 | CLANG_WARN_CONSTANT_CONVERSION = YES; 336 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 337 | CLANG_WARN_EMPTY_BODY = YES; 338 | CLANG_WARN_ENUM_CONVERSION = YES; 339 | CLANG_WARN_INT_CONVERSION = YES; 340 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 341 | CLANG_WARN_UNREACHABLE_CODE = YES; 342 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 343 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 344 | COPY_PHASE_STRIP = NO; 345 | ENABLE_STRICT_OBJC_MSGSEND = YES; 346 | GCC_C_LANGUAGE_STANDARD = gnu99; 347 | GCC_DYNAMIC_NO_PIC = NO; 348 | GCC_OPTIMIZATION_LEVEL = 0; 349 | GCC_PREPROCESSOR_DEFINITIONS = ( 350 | "DEBUG=1", 351 | "$(inherited)", 352 | ); 353 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 354 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 355 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 356 | GCC_WARN_UNDECLARED_SELECTOR = YES; 357 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 358 | GCC_WARN_UNUSED_FUNCTION = YES; 359 | GCC_WARN_UNUSED_VARIABLE = YES; 360 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 361 | MTL_ENABLE_DEBUG_INFO = YES; 362 | ONLY_ACTIVE_ARCH = YES; 363 | SDKROOT = iphoneos; 364 | }; 365 | name = Debug; 366 | }; 367 | 044699A51A028F7400C4E6F1 /* Release */ = { 368 | isa = XCBuildConfiguration; 369 | buildSettings = { 370 | ALWAYS_SEARCH_USER_PATHS = NO; 371 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 372 | CLANG_CXX_LIBRARY = "libc++"; 373 | CLANG_ENABLE_MODULES = YES; 374 | CLANG_ENABLE_OBJC_ARC = YES; 375 | CLANG_WARN_BOOL_CONVERSION = YES; 376 | CLANG_WARN_CONSTANT_CONVERSION = YES; 377 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 378 | CLANG_WARN_EMPTY_BODY = YES; 379 | CLANG_WARN_ENUM_CONVERSION = YES; 380 | CLANG_WARN_INT_CONVERSION = YES; 381 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 382 | CLANG_WARN_UNREACHABLE_CODE = YES; 383 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 384 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 385 | COPY_PHASE_STRIP = YES; 386 | ENABLE_NS_ASSERTIONS = NO; 387 | ENABLE_STRICT_OBJC_MSGSEND = YES; 388 | GCC_C_LANGUAGE_STANDARD = gnu99; 389 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 390 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 391 | GCC_WARN_UNDECLARED_SELECTOR = YES; 392 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 393 | GCC_WARN_UNUSED_FUNCTION = YES; 394 | GCC_WARN_UNUSED_VARIABLE = YES; 395 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 396 | MTL_ENABLE_DEBUG_INFO = NO; 397 | SDKROOT = iphoneos; 398 | VALIDATE_PRODUCT = YES; 399 | }; 400 | name = Release; 401 | }; 402 | 044699A71A028F7400C4E6F1 /* Debug */ = { 403 | isa = XCBuildConfiguration; 404 | buildSettings = { 405 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 406 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 407 | INFOPLIST_FILE = InputHelper/Info.plist; 408 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 409 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 410 | PRODUCT_NAME = "$(TARGET_NAME)"; 411 | }; 412 | name = Debug; 413 | }; 414 | 044699A81A028F7400C4E6F1 /* Release */ = { 415 | isa = XCBuildConfiguration; 416 | buildSettings = { 417 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 418 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 419 | INFOPLIST_FILE = InputHelper/Info.plist; 420 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 421 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 422 | PRODUCT_NAME = "$(TARGET_NAME)"; 423 | }; 424 | name = Release; 425 | }; 426 | 044699AA1A028F7400C4E6F1 /* Debug */ = { 427 | isa = XCBuildConfiguration; 428 | buildSettings = { 429 | BUNDLE_LOADER = "$(TEST_HOST)"; 430 | FRAMEWORK_SEARCH_PATHS = ( 431 | "$(SDKROOT)/Developer/Library/Frameworks", 432 | "$(inherited)", 433 | ); 434 | GCC_PREPROCESSOR_DEFINITIONS = ( 435 | "DEBUG=1", 436 | "$(inherited)", 437 | ); 438 | INFOPLIST_FILE = InputHelperTests/Info.plist; 439 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 440 | PRODUCT_NAME = "$(TARGET_NAME)"; 441 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/InputHelper.app/InputHelper"; 442 | }; 443 | name = Debug; 444 | }; 445 | 044699AB1A028F7400C4E6F1 /* Release */ = { 446 | isa = XCBuildConfiguration; 447 | buildSettings = { 448 | BUNDLE_LOADER = "$(TEST_HOST)"; 449 | FRAMEWORK_SEARCH_PATHS = ( 450 | "$(SDKROOT)/Developer/Library/Frameworks", 451 | "$(inherited)", 452 | ); 453 | INFOPLIST_FILE = InputHelperTests/Info.plist; 454 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 455 | PRODUCT_NAME = "$(TARGET_NAME)"; 456 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/InputHelper.app/InputHelper"; 457 | }; 458 | name = Release; 459 | }; 460 | /* End XCBuildConfiguration section */ 461 | 462 | /* Begin XCConfigurationList section */ 463 | 0446997E1A028F7400C4E6F1 /* Build configuration list for PBXProject "InputHelper" */ = { 464 | isa = XCConfigurationList; 465 | buildConfigurations = ( 466 | 044699A41A028F7400C4E6F1 /* Debug */, 467 | 044699A51A028F7400C4E6F1 /* Release */, 468 | ); 469 | defaultConfigurationIsVisible = 0; 470 | defaultConfigurationName = Release; 471 | }; 472 | 044699A61A028F7400C4E6F1 /* Build configuration list for PBXNativeTarget "InputHelper" */ = { 473 | isa = XCConfigurationList; 474 | buildConfigurations = ( 475 | 044699A71A028F7400C4E6F1 /* Debug */, 476 | 044699A81A028F7400C4E6F1 /* Release */, 477 | ); 478 | defaultConfigurationIsVisible = 0; 479 | defaultConfigurationName = Release; 480 | }; 481 | 044699A91A028F7400C4E6F1 /* Build configuration list for PBXNativeTarget "InputHelperTests" */ = { 482 | isa = XCConfigurationList; 483 | buildConfigurations = ( 484 | 044699AA1A028F7400C4E6F1 /* Debug */, 485 | 044699AB1A028F7400C4E6F1 /* Release */, 486 | ); 487 | defaultConfigurationIsVisible = 0; 488 | defaultConfigurationName = Release; 489 | }; 490 | /* End XCConfigurationList section */ 491 | }; 492 | rootObject = 0446997B1A028F7400C4E6F1 /* Project object */; 493 | } 494 | -------------------------------------------------------------------------------- /InputHelper.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /InputHelper.xcodeproj/project.xcworkspace/xcshareddata/InputHelper.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | F3680042-F6A6-4BB7-9313-7FD0D2F00E57 9 | IDESourceControlProjectName 10 | InputHelper 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 32A1A2687592DEC93A553FE59F2C9BD657FF0D2C 14 | https://github.com/masong2012/InputHelper.git 15 | 16 | IDESourceControlProjectPath 17 | InputHelper.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 32A1A2687592DEC93A553FE59F2C9BD657FF0D2C 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/masong2012/InputHelper.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 32A1A2687592DEC93A553FE59F2C9BD657FF0D2C 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 32A1A2687592DEC93A553FE59F2C9BD657FF0D2C 36 | IDESourceControlWCCName 37 | InputHelper 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /InputHelper.xcodeproj/project.xcworkspace/xcuserdata/Mac.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masong2012/InputHelper/43e40f9b4c8303b1da773cae17771696272cc691/InputHelper.xcodeproj/project.xcworkspace/xcuserdata/Mac.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /InputHelper.xcodeproj/xcuserdata/Mac.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /InputHelper.xcodeproj/xcuserdata/Mac.xcuserdatad/xcschemes/InputHelper.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 94 | 100 | 101 | 102 | 103 | 105 | 106 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /InputHelper.xcodeproj/xcuserdata/Mac.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | InputHelper.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 044699821A028F7400C4E6F1 16 | 17 | primary 18 | 19 | 20 | 0446999B1A028F7400C4E6F1 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /InputHelper/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // InputHelper 4 | // 5 | // Created by MaSong on 14/10/30. 6 | // Copyright (c) 2014年 MaSong. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ViewController.h" 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /InputHelper/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // InputHelper 4 | // 5 | // Created by MaSong on 14/10/30. 6 | // Copyright (c) 2014年 MaSong. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | ViewController *controller = [[ViewController alloc]initWithNibName:@"ViewController" bundle:nil]; 20 | UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:controller]; 21 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 22 | self.window.rootViewController = navController; 23 | [self.window makeKeyAndVisible]; 24 | return YES; 25 | } 26 | 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /InputHelper/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /InputHelper/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /InputHelper/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "minimum-system-version" : "7.0", 7 | "subtype" : "retina4", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "idiom" : "iphone", 12 | "scale" : "1x", 13 | "orientation" : "portrait" 14 | }, 15 | { 16 | "idiom" : "iphone", 17 | "scale" : "2x", 18 | "orientation" : "portrait" 19 | }, 20 | { 21 | "orientation" : "portrait", 22 | "idiom" : "iphone", 23 | "subtype" : "retina4", 24 | "scale" : "2x" 25 | }, 26 | { 27 | "orientation" : "portrait", 28 | "idiom" : "iphone", 29 | "minimum-system-version" : "7.0", 30 | "scale" : "2x" 31 | } 32 | ], 33 | "info" : { 34 | "version" : 1, 35 | "author" : "xcode" 36 | } 37 | } -------------------------------------------------------------------------------- /InputHelper/Images/btn_bg_round_green_290x80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masong2012/InputHelper/43e40f9b4c8303b1da773cae17771696272cc691/InputHelper/Images/btn_bg_round_green_290x80.png -------------------------------------------------------------------------------- /InputHelper/Images/input_box_600x80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masong2012/InputHelper/43e40f9b4c8303b1da773cae17771696272cc691/InputHelper/Images/input_box_600x80.png -------------------------------------------------------------------------------- /InputHelper/Images/input_box_602x203.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masong2012/InputHelper/43e40f9b4c8303b1da773cae17771696272cc691/InputHelper/Images/input_box_602x203.png -------------------------------------------------------------------------------- /InputHelper/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | -900lab.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /InputHelper/InputHelper/InputHelper.h: -------------------------------------------------------------------------------- 1 | /* 2 | *InputHelper 3 | *version 0.1.1 4 | 5 | *thank mario. 6 | 7 | *NOTE: !!(0_0)!! 8 | InputHelper NOT support Autolayout Now!! 9 | 10 | *InputHelper WILL support UITableView and Autolayout. (-_-) 11 | 12 | 2015-01-31 13 | */ 14 | 15 | #import 16 | #import 17 | #define IS_IOS7_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) 18 | 19 | typedef void(^InputHelperDoneBlock)(id); 20 | typedef void(^InputHelperValidationError)(id,NSString*); 21 | 22 | typedef NS_ENUM(NSInteger, InputHelperDismissType) { 23 | 24 | InputHelperDismissTypeNone = 0, 25 | InputHelperDismissTypeCleanMaskView, 26 | InputHelperDismissTypeTapGusture 27 | }; 28 | 29 | typedef NS_ENUM(NSInteger, ValidationType) { 30 | 31 | ValidationTypeNone = 0, //no limit 32 | ValidationTypeNoWhiteSpace, //no whitespace character 33 | ValidationTypeNumberInt, //int number only 34 | ValidationTypePhone, //phone only 35 | ValidationTypeAlphabetAndNumber, //alphabet and number 36 | }; 37 | 38 | 39 | @interface InputHelper : NSObject 40 | 41 | + (InputHelper *)sharedInputHelper; 42 | - (void)dismissInputHelper; 43 | 44 | //keyboard 45 | - (void)setupInputHelperForView:(UIView *)view withDismissType:(InputHelperDismissType)dismissType; 46 | - (void)setupInputHelperForView:(UIView *)view withDismissType:(InputHelperDismissType)dismissType doneBlock:(InputHelperDoneBlock)doneBlock; 47 | 48 | 49 | //validation 50 | - (void)setupValidationType:(ValidationType)type forInputField:(UIView *)inputField; 51 | - (void)limitTextLength:(NSInteger)length forInputField:(UIView *)inputField; 52 | @end 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | @interface NSString (InputHelper) 62 | - (NSString *)trimmedString ; 63 | /* 64 | email: @"^[a-zA-Z0-9][\\w\\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\\w\\.-]*[a-zA-Z0-9]\\.[a-zA-Z][a-zA-Z\\.]*[a-zA-Z]$" 65 | id card: @"^([1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3})|([1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([0-9]|X))$" 66 | phone: @"^1\\d{10}$" 67 | */ 68 | - (BOOL)isTextValidated:(NSString *)validation; 69 | @end 70 | 71 | #define inputHelper [InputHelper sharedInputHelper] -------------------------------------------------------------------------------- /InputHelper/InputHelper/InputHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // InputHelper.m 3 | // InputHelper 4 | // 5 | // Created by MaSong on 13-11-11. 6 | // Copyright (c) 2013年 MaSong. All rights reserved. 7 | // 8 | 9 | #import "InputHelper.h" 10 | #import 11 | #import 12 | 13 | static NSString *kInputHelperTapGusture= @"kInputHelperTapGusture"; 14 | static NSString *kInputHelperDismissType= @"kInputHelperDismissType"; 15 | static NSInteger tapTag = 2014; 16 | 17 | static NSString *kInputHelperRootViewOriginalOriginY = @"kInputHelperRootViewOriginalOriginY"; 18 | static NSString *kInputHelperRootViewOriginalOriginH = @"kInputHelperRootViewOriginalOriginH"; 19 | static NSString *kInputHelperRootViewAllInputFieldOriginYDictionary = @"kInputHelperRootViewAllInputFieldOriginYDictionary"; 20 | static NSString *kInputHelperRootViewSortedInputFieldArray = @"kInputHelperRootViewSortedInputFieldArray"; 21 | 22 | static NSString *kInputHelperDoneBlock = @"kInputHelperDoneBlock"; 23 | 24 | static NSString *kInputHelperValidationType = @"kInputHelperValidationType"; 25 | static NSString *kInputHelperInputFiedlTextLength = @"kInputHelperInputFiedlTextLength"; 26 | static NSString *kInputHelperTextLengthLimit = @"kInputHelperTextLengthLimit"; 27 | 28 | static void setAssociatedObjectForKey(UIView *view ,NSString *key,id value){ 29 | if (view) { 30 | objc_setAssociatedObject(view, (__bridge const void *)(key), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 31 | } 32 | } 33 | 34 | static id getAssociatedObjectForKey(UIView *view ,NSString *key) { 35 | return view ? objc_getAssociatedObject(view, (__bridge const void *)(key)) : nil; 36 | } 37 | 38 | 39 | #define INT_NUMBER_SET @"^\\d*$" 40 | #define PHONE_SET @"^1{1,}\\d*$" 41 | #define ALPHABET_NUMBER_SET @"^[0-9A-Za-z@_.\\-]+$" 42 | 43 | #define INPUT_HELPER_MAX_H [UIScreen mainScreen].bounds.size.height 44 | 45 | @interface InputHelperTapGusture: UITapGestureRecognizer 46 | @property (assign, nonatomic) NSInteger tag; 47 | @end 48 | @implementation InputHelperTapGusture 49 | @end 50 | 51 | 52 | @interface InputHelper () 53 | 54 | @property (strong, nonatomic) UIView *cleanMaskView; 55 | @property (strong, nonatomic) UIToolbar *toolBarForCleanMaskView; 56 | 57 | 58 | @property (strong, nonatomic) UIToolbar *toolBar; 59 | 60 | @property (assign, nonatomic) CGSize keyboardSize; 61 | @property (assign, nonatomic) CGFloat perMoveDistanceForInputField; 62 | 63 | @property (assign, nonatomic) CGRect defaultToolBarFrame; 64 | @property (assign, nonatomic) CGRect defaultMaskViewFrame; 65 | @property (assign, nonatomic) CGRect toolBarFrameInMaskView; 66 | 67 | //current root view 68 | @property (weak, nonatomic) UIView *currentRootView; 69 | 70 | @end 71 | 72 | 73 | @implementation InputHelper 74 | 75 | - (UIToolbar *)createInputHelperToolBar{ 76 | UIToolbar *toolBar = [[UIToolbar alloc]initWithFrame:_defaultToolBarFrame]; 77 | toolBar.barStyle = UIBarStyleBlackTranslucent; 78 | UIBarButtonItem *btnPrevious = [[UIBarButtonItem alloc]initWithTitle:@"上一项" style:UIBarButtonItemStyleDone target:self action:@selector(didClickButtonPrevious)]; 79 | UIBarButtonItem *btnNext = [[UIBarButtonItem alloc]initWithTitle:@"下一项" style:UIBarButtonItemStyleDone target:self action:@selector(didClickButtonNext)]; 80 | UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil]; 81 | UIBarButtonItem *btnDown = [[UIBarButtonItem alloc]initWithTitle:@"完成" style:UIBarButtonItemStyleDone target:self action:@selector(didClickButtonDone)]; 82 | [toolBar setItems:[[NSArray alloc]initWithObjects:btnPrevious,btnNext,spaceItem,btnDown, nil]]; 83 | return toolBar; 84 | } 85 | 86 | 87 | - (void)initilize 88 | { 89 | 90 | _defaultToolBarFrame = CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, 40); 91 | _defaultMaskViewFrame = CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height); 92 | _toolBarFrameInMaskView = CGRectMake(0, [[UIScreen mainScreen] bounds].size.height - 40, [[UIScreen mainScreen] bounds].size.width, 40); 93 | 94 | _perMoveDistanceForInputField = 40; 95 | 96 | _keyboardSize = CGSizeMake(320, 256); 97 | 98 | 99 | //tool bar 100 | self.toolBar = [self createInputHelperToolBar]; 101 | 102 | self.toolBarForCleanMaskView = [self createInputHelperToolBar]; 103 | _toolBarForCleanMaskView.frame = _toolBarFrameInMaskView; 104 | 105 | //tap mask view 106 | _cleanMaskView = [[UIView alloc]initWithFrame:_defaultMaskViewFrame]; 107 | _cleanMaskView.backgroundColor = [UIColor clearColor]; 108 | 109 | UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(didClickButtonDone)]; 110 | [_cleanMaskView addGestureRecognizer:tap]; 111 | [_cleanMaskView addSubview:_toolBarForCleanMaskView]; 112 | 113 | 114 | NSNotificationCenter *notifCenter = [NSNotificationCenter defaultCenter]; 115 | 116 | [notifCenter addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; 117 | [notifCenter addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; 118 | 119 | 120 | [notifCenter addObserver:self selector:@selector(updateFirstResponder:) name:UITextFieldTextDidBeginEditingNotification object:nil]; 121 | [notifCenter addObserver:self selector:@selector(updateFirstResponder:) name:UITextFieldTextDidEndEditingNotification object:nil]; 122 | [notifCenter addObserver:self selector:@selector(updateFirstResponder:) name:UITextViewTextDidBeginEditingNotification object:nil]; 123 | [notifCenter addObserver:self selector:@selector(updateFirstResponder:) name:UITextViewTextDidEndEditingNotification object:nil]; 124 | 125 | 126 | [notifCenter addObserver:self selector:@selector(updateInputFieldText:) name:UITextFieldTextDidChangeNotification object:nil]; 127 | [notifCenter addObserver:self selector:@selector(updateInputFieldText:) name:UITextViewTextDidChangeNotification object:nil]; 128 | 129 | } 130 | 131 | - (instancetype)init{ 132 | self = [super init]; 133 | if (self) { 134 | 135 | [self initilize]; 136 | } 137 | return self; 138 | } 139 | + (InputHelper *)sharedInputHelper{ 140 | static InputHelper *instance; 141 | static dispatch_once_t onceToken; 142 | dispatch_once(&onceToken, ^{ 143 | instance = [[InputHelper alloc]init]; 144 | }); 145 | return instance; 146 | } 147 | 148 | #pragma mark - APIs 149 | - (void)setupInputHelperForView:(UIView *)view withDismissType:(InputHelperDismissType)dismissType doneBlock:(InputHelperDoneBlock)doneBlock{ 150 | 151 | 152 | if ([view isKindOfClass:[UIScrollView class]]) { 153 | 154 | self.currentRootView = view; 155 | 156 | } else { 157 | UIScrollView *scrollView = [[UIScrollView alloc]initWithFrame:view.bounds]; 158 | scrollView.contentSize = view.frame.size; 159 | for(UIView *v in view.subviews){ 160 | [scrollView addSubview:v]; 161 | } 162 | [view insertSubview:scrollView atIndex:0]; 163 | self.currentRootView = scrollView; 164 | } 165 | 166 | 167 | setAssociatedObjectForKey(_currentRootView, kInputHelperRootViewOriginalOriginH, @(_currentRootView.frame.size.height)); 168 | setAssociatedObjectForKey(_currentRootView, kInputHelperDismissType, @(dismissType)); 169 | 170 | NSMutableDictionary *dic= [NSMutableDictionary new]; 171 | setAssociatedObjectForKey(_currentRootView, kInputHelperRootViewAllInputFieldOriginYDictionary, dic); 172 | 173 | NSMutableArray *array = [NSMutableArray new]; 174 | setAssociatedObjectForKey(_currentRootView, kInputHelperRootViewSortedInputFieldArray, array); 175 | 176 | objc_setAssociatedObject(_currentRootView, (__bridge const void *)(kInputHelperDoneBlock), doneBlock, OBJC_ASSOCIATION_COPY_NONATOMIC); 177 | 178 | [self checkInputFieldInView:_currentRootView withViewOriginY:_currentRootView.frame.origin.y]; 179 | 180 | 181 | 182 | NSArray *keys = [getAssociatedObjectForKey(_currentRootView, kInputHelperRootViewAllInputFieldOriginYDictionary) allKeys]; 183 | if (keys.count == 0) { 184 | return; 185 | } 186 | 187 | 188 | NSArray *sortedOriginYArray = [keys sortedArrayUsingComparator:^(id obj1, id obj2){ 189 | if ([obj1 compare:obj2] == NSOrderedDescending){ 190 | return NSOrderedDescending; 191 | } 192 | if ([obj1 compare:obj2] == NSOrderedAscending){ 193 | return NSOrderedAscending; 194 | } 195 | return NSOrderedSame; 196 | }]; 197 | 198 | 199 | UIView *inputAccessoryView = _toolBar; 200 | 201 | if (dismissType == InputHelperDismissTypeNone) { 202 | 203 | _toolBar.frame = _defaultToolBarFrame; 204 | 205 | } else if (dismissType == InputHelperDismissTypeCleanMaskView){ 206 | 207 | inputAccessoryView = _cleanMaskView; 208 | 209 | } else if (dismissType == InputHelperDismissTypeTapGusture){ 210 | 211 | setAssociatedObjectForKey(_currentRootView, kInputHelperTapGusture, kInputHelperTapGusture); 212 | } 213 | 214 | for (NSNumber *key in sortedOriginYArray){ 215 | 216 | UIView *inputField = [getAssociatedObjectForKey(_currentRootView, kInputHelperRootViewAllInputFieldOriginYDictionary) objectForKey:key]; 217 | 218 | [getAssociatedObjectForKey(_currentRootView, kInputHelperRootViewSortedInputFieldArray) addObject:inputField]; 219 | 220 | if ([inputField isKindOfClass:[UITextField class]]) { 221 | 222 | ((UITextField *)inputField).inputAccessoryView = inputAccessoryView; 223 | 224 | } else if([inputField isKindOfClass:[UITextView class]]){ 225 | 226 | ((UITextView *)inputField).inputAccessoryView = inputAccessoryView; 227 | 228 | } else if([inputField isKindOfClass:[UISearchBar class]]){ 229 | 230 | ((UISearchBar *)inputField).inputAccessoryView = inputAccessoryView; 231 | } 232 | 233 | 234 | } 235 | 236 | } 237 | 238 | - (void)setupInputHelperForView:(UIView *)view withDismissType:(InputHelperDismissType)dismissType{ 239 | [self setupInputHelperForView:view withDismissType:dismissType doneBlock:nil]; 240 | } 241 | 242 | - (void)dismissInputHelper{ 243 | [self didClickButtonDone]; 244 | } 245 | 246 | 247 | - (void)setupValidationType:(ValidationType)type forInputField:(UIView *)inputField { 248 | 249 | setAssociatedObjectForKey(inputField, kInputHelperValidationType, @(type)); 250 | 251 | switch (type) { 252 | case ValidationTypeNumberInt: 253 | { 254 | [self setKeyBoardType:UIKeyboardTypeNumberPad forInputField:inputField]; 255 | } 256 | break; 257 | case ValidationTypePhone: 258 | { 259 | [self limitTextLength:11 forInputField:inputField]; 260 | [self setKeyBoardType:UIKeyboardTypePhonePad forInputField:inputField]; 261 | } 262 | break; 263 | default: 264 | { 265 | [self setKeyBoardType:UIKeyboardTypeDefault forInputField:inputField]; 266 | } 267 | break; 268 | } 269 | 270 | } 271 | 272 | 273 | - (void)limitTextLength:(NSInteger)length forInputField:(UIView *)inputField{ 274 | setAssociatedObjectForKey(inputField, kInputHelperTextLengthLimit, @(length)); 275 | } 276 | 277 | #pragma mark - 278 | - (void)updateFirstResponder:(NSNotification *)aNotification { 279 | 280 | [self updateButtonEnabledStateForInputField:[self getFirstResponder]]; 281 | } 282 | 283 | - (void)checkInputFieldInView:(UIView *)view 284 | withViewOriginY:(CGFloat)y 285 | { 286 | 287 | for (UIView *subView in view.subviews){ 288 | 289 | if (subView.hidden == YES) { 290 | continue; 291 | } 292 | 293 | if ([subView isKindOfClass:[UITextField class]] || 294 | [subView isKindOfClass:[UITextView class]] || 295 | [subView isKindOfClass:[UISearchBar class]]) { 296 | 297 | NSNumber *key = [NSNumber numberWithFloat: y + subView.frame.origin.y]; 298 | 299 | NSMutableDictionary *dic = getAssociatedObjectForKey(_currentRootView, kInputHelperRootViewAllInputFieldOriginYDictionary); 300 | [dic setObject:subView forKey:key]; 301 | 302 | } else { 303 | [self checkInputFieldInView:subView 304 | withViewOriginY:y + subView.frame.origin.y]; 305 | } 306 | } 307 | } 308 | 309 | 310 | 311 | - (UIView *)getFirstResponder 312 | { 313 | for (UIView *tf in getAssociatedObjectForKey(_currentRootView, kInputHelperRootViewSortedInputFieldArray)) { 314 | if ([tf isFirstResponder]) { 315 | return tf; 316 | } 317 | } 318 | return nil; 319 | } 320 | 321 | - (void)didClickButtonPrevious 322 | { 323 | UIView *firstResponder = [self getFirstResponder]; 324 | UIView *previousInputField = firstResponder; 325 | NSArray *sortedInputFields = getAssociatedObjectForKey(_currentRootView, kInputHelperRootViewSortedInputFieldArray); 326 | if (![firstResponder isEqual:[sortedInputFields firstObject]]) { 327 | previousInputField = [sortedInputFields objectAtIndex:[sortedInputFields indexOfObject:firstResponder] - 1]; 328 | [previousInputField becomeFirstResponder]; 329 | } 330 | 331 | [self updateButtonEnabledStateForInputField:previousInputField]; 332 | } 333 | 334 | - (void)didClickButtonNext 335 | { 336 | UIView *firstResponder = [self getFirstResponder]; 337 | UIView *nextInputField = firstResponder; 338 | NSArray *sortedInputFields = getAssociatedObjectForKey(_currentRootView, kInputHelperRootViewSortedInputFieldArray); 339 | if (![firstResponder isEqual:[sortedInputFields lastObject]]) { 340 | nextInputField = [sortedInputFields objectAtIndex:[sortedInputFields indexOfObject:firstResponder] + 1]; 341 | [nextInputField becomeFirstResponder]; 342 | } 343 | 344 | 345 | [self updateButtonEnabledStateForInputField:nextInputField]; 346 | } 347 | 348 | - (void)didClickButtonDone 349 | { 350 | 351 | [[self getFirstResponder] resignFirstResponder]; 352 | 353 | CGRect frame = _currentRootView.frame; 354 | frame.origin.y = [getAssociatedObjectForKey(_currentRootView, kInputHelperRootViewOriginalOriginY) floatValue]; 355 | 356 | /* 357 | There may be some bugs.... 358 | frame.origin.y = IS_IOS7_OR_LATER ? 64.0f : 0; 359 | */ 360 | [UIView animateWithDuration:0.3f animations:^{ 361 | _currentRootView.frame = frame; 362 | }]; 363 | 364 | InputHelperDoneBlock doneBlock = getAssociatedObjectForKey(self.currentRootView, kInputHelperDoneBlock); 365 | if (doneBlock) { 366 | //callback what?? 367 | doneBlock(nil); 368 | } 369 | 370 | } 371 | 372 | - (void)updateButtonEnabledStateForInputField:(UIView *)inputField 373 | { 374 | if (inputField) { 375 | NSInteger dismissType = [getAssociatedObjectForKey(_currentRootView, kInputHelperDismissType) integerValue]; 376 | 377 | UIToolbar *toolBar = dismissType == InputHelperDismissTypeCleanMaskView ? _toolBarForCleanMaskView : _toolBar; 378 | UIBarButtonItem *previousBarItem = (UIBarButtonItem *)[[toolBar items] objectAtIndex:0]; 379 | UIBarButtonItem *nextBarItem = (UIBarButtonItem *)[[toolBar items] objectAtIndex:1]; 380 | NSArray *sortedInputFields = getAssociatedObjectForKey(_currentRootView, kInputHelperRootViewSortedInputFieldArray); 381 | [previousBarItem setEnabled:[inputField isEqual:[sortedInputFields firstObject]] ? NO : YES]; 382 | [nextBarItem setEnabled:[inputField isEqual:[sortedInputFields lastObject]] ? NO : YES]; 383 | [self animatedMoveRootViewForInputField:inputField]; 384 | } 385 | 386 | } 387 | 388 | - (void)animatedMoveRootViewForInputField:(UIView *)inputField 389 | { 390 | 391 | CGPoint windowPoint = [inputField.superview convertPoint:inputField.frame.origin toView:[[UIApplication sharedApplication]keyWindow]]; 392 | CGFloat topY = 74.0f; 393 | CGFloat buttomY = [[UIScreen mainScreen]applicationFrame].size.height - _keyboardSize.height - 80; 394 | 395 | CGRect frame = _currentRootView.frame; 396 | if (windowPoint.y < topY ) { 397 | 398 | frame.origin.y += (1 + (int)((topY - windowPoint.y) / _perMoveDistanceForInputField)) * _perMoveDistanceForInputField; 399 | if (frame.origin.y > 0) { 400 | frame.origin.y = 0; 401 | } 402 | 403 | } else if (windowPoint.y > buttomY) { 404 | 405 | frame.origin.y -= ((1 + (int)((windowPoint.y - buttomY) / _perMoveDistanceForInputField)) * _perMoveDistanceForInputField); 406 | } 407 | 408 | [UIView animateWithDuration:0.3f animations:^{ 409 | _currentRootView.frame = frame; 410 | }]; 411 | } 412 | 413 | #pragma mark - Notification methods 414 | 415 | - (void) keyboardWillShow:(NSNotification *) notif 416 | { 417 | 418 | CGFloat keyboardH = [notif.userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue].size.height; 419 | CGFloat originY = [getAssociatedObjectForKey(_currentRootView, kInputHelperRootViewOriginalOriginY) floatValue]; 420 | 421 | CGRect frame = _currentRootView.frame; 422 | frame.size.height = INPUT_HELPER_MAX_H - originY - keyboardH - 40; 423 | ((UIScrollView *)_currentRootView).frame = frame; 424 | 425 | 426 | if (getAssociatedObjectForKey(_currentRootView, kInputHelperRootViewOriginalOriginY) == nil) { 427 | setAssociatedObjectForKey(_currentRootView, kInputHelperRootViewOriginalOriginY, @(_currentRootView.frame.origin.y)); 428 | } 429 | 430 | 431 | NSString *str = getAssociatedObjectForKey(_currentRootView, kInputHelperTapGusture); 432 | 433 | BOOL hasAddGusture = NO; 434 | for(id gusture in _currentRootView.gestureRecognizers){ 435 | if ([gusture isKindOfClass:[InputHelperTapGusture class]] && ((InputHelperTapGusture *)gusture).tag == tapTag) { 436 | hasAddGusture = YES; 437 | break; 438 | } 439 | } 440 | 441 | if ([str isEqualToString:kInputHelperTapGusture] && !hasAddGusture) { 442 | InputHelperTapGusture *tap = [[InputHelperTapGusture alloc]initWithTarget:self action:@selector(didClickButtonDone)]; 443 | tap.tag = tapTag; 444 | [_currentRootView addGestureRecognizer:tap]; 445 | } 446 | 447 | [self updateButtonEnabledStateForInputField:[self getFirstResponder]]; 448 | } 449 | 450 | - (void) keyboardWillHide:(NSNotification *) notif 451 | { 452 | CGFloat originH = [getAssociatedObjectForKey(_currentRootView, kInputHelperRootViewOriginalOriginH) floatValue]; 453 | 454 | CGRect frame = _currentRootView.frame; 455 | frame.size.height = originH; 456 | ((UIScrollView *)_currentRootView).frame = frame; 457 | 458 | NSString *str = getAssociatedObjectForKey(_currentRootView, kInputHelperTapGusture); 459 | 460 | if ([str isEqualToString:kInputHelperTapGusture]) { 461 | for(id gusture in _currentRootView.gestureRecognizers){ 462 | if ([gusture isKindOfClass:[InputHelperTapGusture class]] && ((InputHelperTapGusture *)gusture).tag == tapTag) { 463 | [_currentRootView removeGestureRecognizer:gusture]; 464 | break; 465 | } 466 | } 467 | } 468 | 469 | [self dismissInputHelper]; 470 | } 471 | 472 | 473 | - (void)updateInputFieldText:(NSNotification *)notif{ 474 | [self checkInputField:notif.object]; 475 | } 476 | 477 | #pragma mark - Validation 478 | 479 | - (void)setKeyBoardType:(UIKeyboardType) keyboardType forInputField:(UIView *)inputField{ 480 | if ([inputField isKindOfClass:[UITextField class]]) { 481 | ((UITextField *)inputField).keyboardType = keyboardType; 482 | } else if([inputField isKindOfClass:[UITextView class]]){ 483 | ((UITextView *)inputField).keyboardType = keyboardType; 484 | } else if([inputField isKindOfClass:[UISearchBar class]]){ 485 | ((UISearchBar *)inputField).keyboardType = keyboardType; 486 | } 487 | } 488 | 489 | - (NSString *)getTextForInputField:(UIView *)inputField{ 490 | if ([inputField isKindOfClass:[UITextField class]]) { 491 | return ((UITextField *)inputField).text; 492 | } else if([inputField isKindOfClass:[UITextView class]]){ 493 | return ((UITextView *)inputField).text; 494 | } else if([inputField isKindOfClass:[UISearchBar class]]){ 495 | return ((UISearchBar *)inputField).text; 496 | } 497 | return @""; 498 | } 499 | 500 | - (void)setText:(NSString *)text forInputField:(UIView *)inputField{ 501 | if ([inputField isKindOfClass:[UITextField class]]) { 502 | ((UITextField *)inputField).text = text; 503 | } else if([inputField isKindOfClass:[UITextView class]]){ 504 | ((UITextView *)inputField).text = text; 505 | } else if([inputField isKindOfClass:[UISearchBar class]]){ 506 | ((UISearchBar *)inputField).text = text; 507 | } 508 | } 509 | 510 | - (void)checkText:(NSString *)text forInputField:(UIView *)inputField validation:(NSString *)validation{ 511 | 512 | NSInteger preLength = [getAssociatedObjectForKey(inputField, kInputHelperInputFiedlTextLength) integerValue]; 513 | NSLog(@"current text %@ len %d,prelen %d",text,[text length],preLength); 514 | 515 | if (![self isTextAvailable:text forValidation:validation]) { 516 | [self setText:[text substringToIndex:MAX(MAX(preLength - 1, 0), text.length -1)] forInputField:inputField]; 517 | setAssociatedObjectForKey(inputField, kInputHelperInputFiedlTextLength, @(preLength)); 518 | } else { 519 | setAssociatedObjectForKey(inputField, kInputHelperInputFiedlTextLength, @(text.length)); 520 | } 521 | 522 | } 523 | 524 | - (void)checkInputField:(UIView *)inputField{ 525 | 526 | NSInteger type = [getAssociatedObjectForKey(inputField, kInputHelperValidationType) integerValue]; 527 | 528 | //length limit 529 | NSInteger limitLength = [getAssociatedObjectForKey(inputField, kInputHelperTextLengthLimit) integerValue]; 530 | if (limitLength) { 531 | NSString *text = [self getTextForInputField:inputField]; 532 | if (text.length && text.length > limitLength) { 533 | [self setText:[text substringToIndex:limitLength]forInputField:inputField]; 534 | } 535 | } 536 | 537 | 538 | NSString *text = [self getTextForInputField:inputField]; 539 | 540 | if (text.length) { 541 | 542 | switch (type) { 543 | case ValidationTypeNone: 544 | { 545 | //do nothing 546 | } 547 | break; 548 | case ValidationTypeNoWhiteSpace: 549 | { 550 | [self setText:[text trimmedString] forInputField:inputField]; 551 | } 552 | break; 553 | case ValidationTypeNumberInt: 554 | { 555 | [self checkText:text forInputField:inputField validation:INT_NUMBER_SET]; 556 | } 557 | break; 558 | case ValidationTypeAlphabetAndNumber: 559 | { 560 | [self checkText:text forInputField:inputField validation:ALPHABET_NUMBER_SET]; 561 | } 562 | break; 563 | case ValidationTypePhone: 564 | { 565 | [self checkText:text forInputField:inputField validation:PHONE_SET]; 566 | } 567 | break; 568 | default: 569 | { 570 | } 571 | break; 572 | } 573 | 574 | 575 | } 576 | } 577 | 578 | 579 | - (BOOL)isTextAvailable:(NSString *)text forValidation:(NSString *)validation { 580 | NSPredicate *regexPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",validation]; 581 | return [regexPredicate evaluateWithObject:text]; 582 | } 583 | 584 | @end 585 | 586 | 587 | 588 | @implementation NSString (InputHelper) 589 | 590 | - (NSString *)trimmedString { 591 | return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 592 | } 593 | 594 | - (BOOL)isTextValidated:(NSString *)validation{ 595 | NSPredicate *regexPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",validation]; 596 | return [regexPredicate evaluateWithObject:self]; 597 | } 598 | @end 599 | 600 | -------------------------------------------------------------------------------- /InputHelper/TestControllers/BaseViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // BaseViewController.h 3 | // InputHelper 4 | // 5 | // Created by MaSong on 15/1/11. 6 | // Copyright (c) 2015年 MaSong. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "InputHelper.h" 11 | @interface BaseViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /InputHelper/TestControllers/BaseViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // BaseViewController.m 3 | // InputHelper 4 | // 5 | // Created by MaSong on 15/1/11. 6 | // Copyright (c) 2015年 MaSong. All rights reserved. 7 | // 8 | 9 | #import "BaseViewController.h" 10 | 11 | @interface BaseViewController () 12 | 13 | @end 14 | 15 | @implementation BaseViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]){ 20 | self.edgesForExtendedLayout = UIRectEdgeNone; 21 | } 22 | } 23 | 24 | 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /InputHelper/TestControllers/UIScrollViewTest_ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIScrollViewTest_ViewController.h 3 | // InputHelper 4 | // 5 | // Created by MaSong on 15/1/8. 6 | // Copyright (c) 2015年 MaSong. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "BaseViewController.h" 11 | @interface UIScrollViewTest_ViewController : BaseViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /InputHelper/TestControllers/UIScrollViewTest_ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIScrollViewTest_ViewController.m 3 | // InputHelper 4 | // 5 | // Created by MaSong on 15/1/8. 6 | // Copyright (c) 2015年 MaSong. All rights reserved. 7 | // 8 | 9 | #import "UIScrollViewTest_ViewController.h" 10 | 11 | @interface UIScrollViewTest_ViewController () 12 | @property (weak, nonatomic) IBOutlet UIScrollView *scrollView; 13 | 14 | @end 15 | 16 | @implementation UIScrollViewTest_ViewController 17 | 18 | - (void)viewDidLoad { 19 | [super viewDidLoad]; 20 | 21 | [inputHelper setupInputHelperForView:self.scrollView withDismissType:InputHelperDismissTypeTapGusture]; 22 | 23 | } 24 | 25 | 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /InputHelper/TestControllers/UIScrollViewTest_ViewController.xib: -------------------------------------------------------------------------------- 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 | 41 | 48 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /InputHelper/TestControllers/UIViewTest_ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewTest_ViewController.h 3 | // InputHelper 4 | // 5 | // Created by MaSong on 15/1/8. 6 | // Copyright (c) 2015年 MaSong. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "BaseViewController.h" 11 | 12 | @interface UIViewTest_ViewController : BaseViewController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /InputHelper/TestControllers/UIViewTest_ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewTest_ViewController.m 3 | // InputHelper 4 | // 5 | // Created by MaSong on 15/1/8. 6 | // Copyright (c) 2015年 MaSong. All rights reserved. 7 | // 8 | 9 | #import "UIViewTest_ViewController.h" 10 | 11 | @interface UIViewTest_ViewController () 12 | @property (weak, nonatomic) IBOutlet UITextField *ageTextField; 13 | @property (weak, nonatomic) IBOutlet UITextField *nameTextField; 14 | @property (weak, nonatomic) IBOutlet UITextView *textView; 15 | 16 | @end 17 | 18 | @implementation UIViewTest_ViewController 19 | 20 | - (void)viewDidLoad { 21 | [super viewDidLoad]; 22 | [inputHelper setupInputHelperForView:self.view withDismissType:InputHelperDismissTypeTapGusture]; 23 | 24 | 25 | [inputHelper setupValidationType:ValidationTypeNumberInt forInputField:_ageTextField]; 26 | 27 | [inputHelper limitTextLength:20 forInputField:_textView]; 28 | } 29 | 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /InputHelper/TestControllers/UIViewTest_ViewController.xib: -------------------------------------------------------------------------------- 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 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /InputHelper/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // InputHelper 4 | // 5 | // Created by MaSong on 14/10/30. 6 | // Copyright (c) 2014年 MaSong. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UIViewTest_ViewController.h" 11 | #import "UIScrollViewTest_ViewController.h" 12 | 13 | @interface ViewController : UIViewController 14 | 15 | @end 16 | 17 | -------------------------------------------------------------------------------- /InputHelper/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // InputHelper 4 | // 5 | // Created by MaSong on 14/10/30. 6 | // Copyright (c) 2014年 MaSong. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "InputHelper/InputHelper.h" 11 | @interface ViewController () 12 | 13 | @end 14 | 15 | @implementation ViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | 20 | if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]){ 21 | self.edgesForExtendedLayout = UIRectEdgeNone; 22 | } 23 | 24 | self.title = @"InputHelper Test"; 25 | } 26 | - (IBAction)testUIViewAction:(id)sender { 27 | [self.navigationController pushViewController:[[UIViewTest_ViewController alloc]initWithNibName:@"UIViewTest_ViewController" bundle:nil] animated:YES]; 28 | } 29 | - (IBAction)testUIScrollViewAction:(id)sender { 30 | [self.navigationController pushViewController:[[UIScrollViewTest_ViewController alloc]initWithNibName:@"UIScrollViewTest_ViewController" bundle:nil] animated:YES]; 31 | } 32 | 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /InputHelper/ViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 25 | 35 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /InputHelper/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // InputHelper 4 | // 5 | // Created by MaSong on 14/10/30. 6 | // Copyright (c) 2014年 MaSong. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /InputHelperTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | -900lab.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /InputHelperTests/InputHelperTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // InputHelperTests.m 3 | // InputHelperTests 4 | // 5 | // Created by MaSong on 14/10/30. 6 | // Copyright (c) 2014年 MaSong. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface InputHelperTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation InputHelperTests 17 | 18 | - (void)setUp { 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 | // Put teardown code here. This method is called after the invocation of each test method in the class. 25 | [super tearDown]; 26 | } 27 | 28 | - (void)testExample { 29 | // This is an example of a functional test case. 30 | XCTAssert(YES, @"Pass"); 31 | } 32 | 33 | - (void)testPerformanceExample { 34 | // This is an example of a performance test case. 35 | [self measureBlock:^{ 36 | // Put the code you want to measure the time of here. 37 | }]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 masong 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, 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, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | InputHelper 2 | =========== 3 | #NOTE: InputHelper Not Support UITableView And Autolayout Now. 4 | =========== 5 | #How to use ? 6 | 7 | *** 8 | *[inputHelper setupInputHelperForView:view withDismissType:InputHelperDismissTypeNone];* 9 | >Keyboard will hide when you click the done button 10 | 11 | #OR 12 | *[inputHelper setupInputHelperForView:view withDismissType:InputHelperDismissTypeCleanMaskView];* 13 | >Keyboard will hide when you Touch outside of the Keyboard 14 | 15 | #OR 16 | *[inputHelper setupInputHelperForView:view withDismissType:InputHelperDismissTypeTapGusture];* 17 | >Keyboard will hide when you Touch the view 18 | *** 19 | 20 | AND YOU CAN USER THOSE METHODS FOR A CONTROLLER,JUST USE controller.view . 21 | 22 | JUST NEED ONE LINE CODES,IT CAN AUTO ADJUST THE FRAME OF THE 23 | #UITextField/UITextView/UISearchBar 24 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman --------------------------------------------------------------------------------