├── _config.yml
├── InputHelper
├── Images
│ ├── input_box_600x80.png
│ ├── input_box_602x203.png
│ └── btn_bg_round_green_290x80.png
├── TestControllers
│ ├── BaseViewController.h
│ ├── UIViewTest_ViewController.h
│ ├── UIScrollViewTest_ViewController.h
│ ├── BaseViewController.m
│ ├── UIScrollViewTest_ViewController.m
│ ├── UIViewTest_ViewController.m
│ ├── UIViewTest_ViewController.xib
│ └── UIScrollViewTest_ViewController.xib
├── ViewController.h
├── AppDelegate.h
├── main.m
├── Images.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── LaunchImage.launchimage
│ │ └── Contents.json
├── AppDelegate.m
├── ViewController.m
├── Info.plist
├── InputHelper
│ ├── InputHelper.h
│ └── InputHelper.m
├── Base.lproj
│ └── LaunchScreen.xib
└── ViewController.xib
├── InputHelper.xcodeproj
├── xcuserdata
│ └── Mac.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── InputHelper.xcscheme
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcuserdata
│ │ └── Mac.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcshareddata
│ │ └── InputHelper.xccheckout
└── project.pbxproj
├── README.md
├── InputHelperTests
├── Info.plist
└── InputHelperTests.m
├── InputHelper.podspec
└── LICENSE
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-cayman
--------------------------------------------------------------------------------
/InputHelper/Images/input_box_600x80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/masong2012/InputHelper/HEAD/InputHelper/Images/input_box_600x80.png
--------------------------------------------------------------------------------
/InputHelper/Images/input_box_602x203.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/masong2012/InputHelper/HEAD/InputHelper/Images/input_box_602x203.png
--------------------------------------------------------------------------------
/InputHelper/Images/btn_bg_round_green_290x80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/masong2012/InputHelper/HEAD/InputHelper/Images/btn_bg_round_green_290x80.png
--------------------------------------------------------------------------------
/InputHelper.xcodeproj/xcuserdata/Mac.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/InputHelper.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/InputHelper.xcodeproj/project.xcworkspace/xcuserdata/Mac.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/masong2012/InputHelper/HEAD/InputHelper.xcodeproj/project.xcworkspace/xcuserdata/Mac.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/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/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/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/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/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/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 |
--------------------------------------------------------------------------------
/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.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.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/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 | }
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/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/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.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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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.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/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/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/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.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/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/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.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/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 |
--------------------------------------------------------------------------------