├── .gitignore ├── .swift-version ├── Classes └── CXXkeyBoard │ ├── CXXBaseKeyBoard │ ├── XMBasekeyBoardView.h │ └── XMBasekeyBoardView.m │ ├── CarContentKeyBoard │ ├── CarContentKeyBoard.h │ └── CarContentKeyBoard.m │ ├── CarNumHeaderKeyBoard │ ├── XMCarNumHeaderKeyBoard.h │ └── XMCarNumHeaderKeyBoard.m │ ├── CharKeyBoard │ ├── XMCharKeyBoardView.h │ └── XMCharKeyBoardView.m │ ├── KeyBoardSource.Bundle │ ├── CXXshift@2x.png │ ├── c_chaKeyboardButton.png │ ├── c_chaKeyboardButton@2x.png │ ├── c_chaKeyboardButtonSel.png │ ├── c_chaKeyboardButtonSel@2x.png │ ├── c_chaKeyboardShiftButton.png │ ├── c_chaKeyboardShiftButton@2x.png │ ├── c_chaKeyboardShiftButtonSel.png │ ├── c_chaKeyboardShiftButtonSel@2x.png │ ├── c_character_keyboardDeleteButton.png │ ├── c_character_keyboardDeleteButton@2x.png │ ├── c_character_keyboardDeleteButtonSel.png │ ├── c_character_keyboardDeleteButtonSel@2x.png │ ├── c_character_keyboardSwitchButton.png │ ├── c_character_keyboardSwitchButton@2x.png │ ├── c_character_keyboardSwitchButtonSel.png │ ├── c_character_keyboardSwitchButtonSel@2x.png │ ├── emoji_touch.png │ ├── emoji_touch@2x.png │ ├── newcapsLock.png │ ├── newcapsLock@2x.png │ ├── newcapsLock@3x.png │ ├── newdelete.png │ ├── newdelete@2x.png │ └── newdelete@3x.png │ ├── NumKeyBoardStyleOne │ ├── XMNumberKeyBoardStyleOne.h │ └── XMNumberKeyBoardStyleOne.m │ ├── NumKeyboard │ ├── XMNumberkeyBoard.h │ └── XMNumberkeyBoard.m │ ├── NumStrongKeyBoard │ ├── XMNumStrongKeyBoard.h │ └── XMNumStrongKeyBoard.m │ ├── Tools │ ├── UIView+XMFrame.h │ └── UIView+XMFrame.m │ ├── WordKeyBoard │ ├── XMWordKeyBoardView.h │ └── XMWordKeyBoardView.m │ ├── XMKeyBoardHeader.h │ ├── XMKeyBoardView.h │ ├── XMKeyBoardView.m │ ├── XMTextField.h │ └── XMTextField.m ├── LICENSE ├── README.md ├── XMTXCustomKeyBoard.podspec └── XMTXCustomKeyBoard ├── XMTXCustomKeyBoard.xcodeproj ├── project.pbxproj └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── XMTXCustomKeyBoard ├── .swift-version ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist ├── UITextField+CHTHealper.h ├── UITextField+CHTHealper.m ├── ViewController.h ├── ViewController.m └── main.m ├── XMTXCustomKeyBoardTests ├── Info.plist └── XMTXCustomKeyBoardTests.m └── XMTXCustomKeyBoardUITests ├── Info.plist └── XMTXCustomKeyBoardUITests.m /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | # CocoaPods 32 | # 33 | # We recommend against adding the Pods directory to your .gitignore. However 34 | # you should judge for yourself, the pros and cons are mentioned at: 35 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 36 | # 37 | # Pods/ 38 | 39 | # Carthage 40 | # 41 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 42 | # Carthage/Checkouts 43 | 44 | Carthage/Build 45 | 46 | # fastlane 47 | # 48 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 49 | # screenshots whenever they are needed. 50 | # For more information about the recommended setup visit: 51 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 52 | 53 | fastlane/report.xml 54 | fastlane/Preview.html 55 | fastlane/screenshots/**/*.png 56 | fastlane/test_output 57 | 58 | # Code Injection 59 | # 60 | # After new code Injection tools there's a generated folder /iOSInjectionProject 61 | # https://github.com/johnno1962/injectionforxcode 62 | 63 | iOSInjectionProject/ 64 | -------------------------------------------------------------------------------- /.swift-version: -------------------------------------------------------------------------------- 1 | 3.0 2 | -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/CXXBaseKeyBoard/XMBasekeyBoardView.h: -------------------------------------------------------------------------------- 1 | // 2 | // XMBasekeyBoardView.h 3 | // chexiaoxi 4 | // 5 | // Created by 风吹裤衩 on 2018/6/29. 6 | // Copyright © 2018年 风吹裤衩. All rights reserved. 7 | /* 8 | ********************************************************************************* 9 | * 10 | * 这里 自定义键盘的公共配置和基类。 考虑以后扩展,暂时做个base 放在这里 11 | * 12 | * 13 | * 里面实现了创建按,删除。退格等 创建方式。子类继承此类,实现对应UI即可 14 | * 15 | ********************************************************************************* 16 | */ 17 | 18 | #import 19 | #import "XMKeyBoardHeader.h" 20 | 21 | 22 | @class SwitchBtn,DeleteBtn,ClearBtn,HiddenBtn,DetermineBtn,CapsLockBtn,SpaceBtn,fixedBtn; 23 | 24 | typedef NS_ENUM(NSInteger,XMKeyBoardBtnType) 25 | { 26 | XMKeyBoardBtnType_Cancle, //取消 27 | XMKeyBoardBtnType_Clear,//清空 28 | XMKeyBoardBtnType_Dlelte,//退格 29 | XMKeyBoardBtnType_Hidden,//隐藏 30 | }; 31 | 32 | @protocol XMkeyBoardViewDelegate 33 | 34 | @optional 35 | 36 | /** 点击了键盘上的内容按钮 */ 37 | -(UIButton *)xmClickConten:(UIButton *)contenBtn; 38 | 39 | /** 点击了键盘上的删除按钮 */ 40 | -(DeleteBtn *)xmClickDelete:(DeleteBtn *)deleteBtn; 41 | 42 | /** 点击了键盘上的清空按钮 */ 43 | -(ClearBtn *)xmClickClear:(ClearBtn *)clearBtn; 44 | 45 | /** 点击了键盘上的隐藏按钮 */ 46 | -(HiddenBtn *)xmClickHidden:(HiddenBtn *)hiddenBtn; 47 | 48 | /** 点击了键盘上的确定按钮 */ 49 | -(DetermineBtn *)xmClickdetermine:(DetermineBtn *)determineBtn; 50 | 51 | /** 点击了键盘上的切换按钮 */ 52 | -(SwitchBtn *)xmClickswitch:(SwitchBtn *)switchBtn; 53 | 54 | /** 点击了键盘上的字母大小写的切换按钮 */ 55 | -(CapsLockBtn *)xmClickcapsLock:(CapsLockBtn *)switchBtn; 56 | 57 | /** 点击了键盘上的空格 */ 58 | -(SpaceBtn *)xmClickspace:(SpaceBtn *)spaceBtn; 59 | 60 | /** 点击了键盘上的固定按钮 */ 61 | -(fixedBtn *)xmClickfixedBtn:(fixedBtn *)fixedBtn; 62 | 63 | /** 大小写切换事件处理 */ 64 | -(UIButton *)xmClicklowExchangeAcapital:(UIButton *)btn; 65 | 66 | 67 | @end 68 | 69 | 70 | @interface DeleteBtn : UIButton 71 | 72 | @end 73 | 74 | @interface ClearBtn : UIButton 75 | 76 | @end 77 | 78 | @interface HiddenBtn : UIButton 79 | 80 | @end 81 | 82 | @interface DetermineBtn : UIButton 83 | 84 | @end 85 | 86 | @interface SwitchBtn : UIButton 87 | 88 | @end 89 | 90 | @interface SpaceBtn : UIButton 91 | 92 | @end 93 | 94 | @interface CapsLockBtn : UIButton 95 | 96 | @end 97 | 98 | @interface fixedBtn : UIButton 99 | 100 | @end 101 | 102 | @interface XMBasekeyBoardView : UIView 103 | 104 | /** 配置公共的UI */ 105 | -(void)setUI ; 106 | 107 | /** 点击事件传递 */ 108 | @property (nonatomic,copy)XMCallBackBlock cilckBlock; 109 | 110 | @property (nonatomic,weak) id delegate; 111 | 112 | 113 | /** 快速创建退格按钮 */ 114 | -(DeleteBtn *)creatDeleteBtn; 115 | 116 | /** 快速创建清空按钮 */ 117 | -(ClearBtn *)creatClearBtn; 118 | 119 | /** 快速创建隐藏按钮 */ 120 | -(HiddenBtn *)creatHiddenBtn; 121 | 122 | /** 快速创建确定按钮 */ 123 | -(DetermineBtn *)creatDetermineBtnBtn; 124 | 125 | /** 快速创建切换数字和字母的按钮 */ 126 | -(SwitchBtn *)creatSwitchBtn; 127 | 128 | /** 快速创建空格按钮 */ 129 | -(SpaceBtn *)creatSpaceBtn; 130 | 131 | /** 快速创建大小写切换按钮 */ 132 | -(CapsLockBtn *)creatCapsLockBtn; 133 | 134 | /** 快速创建固定输入数字的按钮 */ 135 | -(fixedBtn *)creatfixedBtn; 136 | 137 | /** 快速创建普通按钮 */ 138 | -(UIButton *)creatNormalBtn; 139 | 140 | 141 | @end 142 | -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/CXXBaseKeyBoard/XMBasekeyBoardView.m: -------------------------------------------------------------------------------- 1 | // 2 | // XMBasekeyBoardView.m 3 | // chexiaoxi 4 | // 5 | // Created by 风吹裤衩 on 2018/6/29. 6 | // Copyright © 2018年 风吹裤衩. All rights reserved. 7 | // 8 | 9 | #import "XMBasekeyBoardView.h" 10 | 11 | @implementation XMBasekeyBoardView 12 | 13 | -(instancetype)init 14 | { 15 | if (self = [super init]) { 16 | [self setUI]; 17 | } 18 | return self; 19 | } 20 | 21 | -(void)setUI 22 | { 23 | self.backgroundColor = keyBoardBackviewcolor; 24 | } 25 | 26 | /** 快速创建退格按钮 */ 27 | -(DeleteBtn *)creatDeleteBtn 28 | { 29 | DeleteBtn *Btn = [DeleteBtn buttonWithType:UIButtonTypeCustom]; 30 | [self defaultBtnConfiger:Btn]; 31 | return Btn ; 32 | } 33 | 34 | /** 快速创建清空按钮 */ 35 | -(ClearBtn *)creatClearBtn 36 | { 37 | ClearBtn *Btn = [ClearBtn buttonWithType:UIButtonTypeCustom]; 38 | [self defaultBtnConfiger:Btn]; 39 | return Btn ; 40 | } 41 | 42 | /** 快速创建隐藏按钮 */ 43 | -(HiddenBtn *)creatHiddenBtn 44 | { 45 | HiddenBtn *Btn = [HiddenBtn buttonWithType:UIButtonTypeCustom]; 46 | [self defaultBtnConfiger:Btn]; 47 | return Btn ; 48 | } 49 | 50 | /** 快速创建确定按钮 */ 51 | -(DetermineBtn *)creatDetermineBtnBtn 52 | { 53 | DetermineBtn *Btn = [DetermineBtn buttonWithType:UIButtonTypeCustom]; 54 | [self defaultBtnConfiger:Btn]; 55 | return Btn ; 56 | } 57 | 58 | /** 快速创建切换数字和字母的按钮 */ 59 | -(SwitchBtn *)creatSwitchBtn 60 | { 61 | SwitchBtn *Btn = [SwitchBtn buttonWithType:UIButtonTypeCustom]; 62 | [self defaultBtnConfiger:Btn]; 63 | return Btn ; 64 | } 65 | 66 | /** 快速创建空格按钮 */ 67 | -(SpaceBtn *)creatSpaceBtn 68 | { 69 | SpaceBtn *Btn = [SpaceBtn buttonWithType:UIButtonTypeCustom]; 70 | [self defaultBtnConfiger:Btn]; 71 | return Btn ; 72 | } 73 | 74 | /** 快速创建大小写切换按钮 */ 75 | -(CapsLockBtn *)creatCapsLockBtn 76 | { 77 | CapsLockBtn *Btn = [CapsLockBtn buttonWithType:UIButtonTypeCustom]; 78 | [self defaultBtnConfiger:Btn]; 79 | return Btn ; 80 | } 81 | 82 | /** 快速创建普通按钮 */ 83 | -(UIButton *)creatNormalBtn 84 | { 85 | UIButton *Btn = [UIButton buttonWithType:UIButtonTypeCustom]; 86 | [self defaultBtnConfiger:Btn]; 87 | return Btn ; 88 | } 89 | -(fixedBtn *)creatfixedBtn 90 | { 91 | fixedBtn *Btn = [fixedBtn buttonWithType:UIButtonTypeCustom]; 92 | [self defaultBtnConfiger:Btn]; 93 | return Btn ; 94 | } 95 | 96 | -(void)defaultBtnConfiger:(UIButton *)btn 97 | { 98 | btn.backgroundColor = [UIColor whiteColor];; 99 | btn.titleLabel.font = [UIFont systemFontOfSize:18]; 100 | [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 101 | [btn setTitleColor:[UIColor orangeColor] forState:UIControlStateHighlighted]; 102 | [btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside]; 103 | } 104 | 105 | -(void)btnClick:(UIButton *)cilckBtn 106 | { 107 | if (self.cilckBlock) { 108 | self.cilckBlock(cilckBtn); 109 | } 110 | if ([[cilckBtn class] isEqual:[CapsLockBtn class]]) { 111 | [self.delegate xmClicklowExchangeAcapital:(CapsLockBtn *)cilckBtn]; //大小写切换 112 | } 113 | else if([[cilckBtn class] isEqual:[DeleteBtn class]]){ 114 | [self.delegate xmClickDelete:(DeleteBtn *)cilckBtn]; //退格 115 | } 116 | else if([[cilckBtn class] isEqual:[SwitchBtn class]]){ 117 | [self.delegate xmClickswitch:(SwitchBtn *)cilckBtn];//切换word和数字键盘 118 | } 119 | else if([[cilckBtn class] isEqual:[HiddenBtn class]]){ // 隐藏 120 | [self.delegate xmClickHidden:(HiddenBtn *)cilckBtn]; 121 | } 122 | else if([[cilckBtn class] isEqual:[SpaceBtn class]]){// 空格 123 | [self.delegate xmClickspace:(SpaceBtn *)cilckBtn]; 124 | } 125 | else if([[cilckBtn class] isEqual:[DetermineBtn class]]){ //确定 126 | [self.delegate xmClickdetermine:(DetermineBtn *)cilckBtn]; 127 | } 128 | else if([[cilckBtn class] isEqual:[ClearBtn class]]){ //请客 129 | [self.delegate xmClickClear:(ClearBtn *)cilckBtn]; 130 | } 131 | else{ 132 | [self.delegate xmClickConten:cilckBtn]; //字母按钮 133 | } 134 | } 135 | 136 | /** 点击了字母 */ 137 | -(UIButton *)xmClickConten:(UIButton *)btn 138 | { 139 | if ([self.delegate respondsToSelector:@selector(xmClickConten:)]) { 140 | [self.delegate xmClickConten:btn]; 141 | } 142 | return btn; 143 | } 144 | 145 | /** 大小写切换事件处理 ,不作处理子类实现此方法 */ 146 | -(UIButton *)xmClicklowExchangeAcapital:(UIButton *)btn 147 | { 148 | 149 | return btn; 150 | } 151 | 152 | /** 退格 */ 153 | -(DeleteBtn *)xmClickDelete:(DeleteBtn *)btn 154 | { 155 | if ([self.delegate respondsToSelector:@selector(xmClickDelete:)]) { 156 | [self.delegate xmClickDelete:btn]; 157 | } 158 | return btn; 159 | } 160 | 161 | /** 数字字母切换 */ 162 | -(SwitchBtn *)xmClickswitch:(SwitchBtn *)btn 163 | { 164 | if ([self.delegate respondsToSelector:@selector(xmClickswitch:)]) { 165 | [self.delegate xmClickswitch:btn]; 166 | } 167 | return btn; 168 | } 169 | 170 | /** 隐藏键盘 */ 171 | -(HiddenBtn *)xmClickHidden:(HiddenBtn *)btn 172 | { 173 | if ([self.delegate respondsToSelector:@selector(xmClickHidden:)]) { 174 | [self.delegate xmClickHidden:btn]; 175 | } 176 | return btn; 177 | } 178 | 179 | /** 点击了空格 */ 180 | -(SpaceBtn *)xmClickspace:(SpaceBtn *)btn 181 | { 182 | if ([self.delegate respondsToSelector:@selector(xmClickspace:)]) { 183 | [self.delegate xmClickspace:btn]; 184 | } 185 | return btn; 186 | } 187 | 188 | /** 点击了确定 */ 189 | -(DetermineBtn *)xmClickdetermine:(DetermineBtn *)btn 190 | { 191 | if ([self.delegate respondsToSelector:@selector(xmClickdetermine:)]) { 192 | [self.delegate xmClickdetermine:btn]; 193 | } 194 | return btn; 195 | } 196 | 197 | 198 | @end 199 | 200 | @implementation SwitchBtn 201 | 202 | @end 203 | 204 | @implementation SpaceBtn 205 | 206 | @end 207 | 208 | @implementation DetermineBtn 209 | 210 | @end 211 | 212 | @implementation HiddenBtn 213 | 214 | @end 215 | 216 | @implementation ClearBtn 217 | 218 | @end 219 | 220 | @implementation DeleteBtn 221 | 222 | @end 223 | 224 | @implementation CapsLockBtn 225 | 226 | @end 227 | 228 | @implementation fixedBtn 229 | 230 | @end 231 | 232 | -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/CarContentKeyBoard/CarContentKeyBoard.h: -------------------------------------------------------------------------------- 1 | // 2 | // CarContentKeyBoard.h 3 | // XMTXCustomKeyBoard 4 | // 5 | // Created by 风吹裤衩 on 2018/11/15. 6 | // Copyright © 2018年 风吹裤衩. All rights reserved. 7 | // 8 | 9 | #import "XMBasekeyBoardView.h" 10 | 11 | @interface CarContentKeyBoard : XMBasekeyBoardView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/CarContentKeyBoard/CarContentKeyBoard.m: -------------------------------------------------------------------------------- 1 | // 2 | // CarContentKeyBoard.m 3 | // XMTXCustomKeyBoard 4 | // 5 | // Created by 风吹裤衩 on 2018/11/15. 6 | // Copyright © 2018年 风吹裤衩. All rights reserved. 7 | // 8 | 9 | #import "CarContentKeyBoard.h" 10 | 11 | @interface CarContentKeyBoard() 12 | { 13 | CGFloat topMargin ; //上面的距离 14 | CGFloat bottomMargin ; //下面的距离 15 | CGFloat leftMargin ; //最左边的距离 16 | CGFloat colMargin ;//行间距 17 | CGFloat rowMargin ;//列间距 18 | CGFloat topBtnW ; //按钮的宽度 19 | CGFloat topBtnH ; //按钮的高度 20 | } 21 | 22 | /** 装载切割好了的字符串 */ 23 | @property (nonatomic,strong)NSMutableArray *dataSource; 24 | 25 | /** 退格按钮 */ 26 | @property (nonatomic,strong)DeleteBtn *deleteBtn; 27 | 28 | /** 字符和数字的切换按钮 */ 29 | @property (nonatomic,strong)SwitchBtn *switchBtn; 30 | @end 31 | 32 | @implementation CarContentKeyBoard 33 | 34 | -(instancetype)initWithFrame:(CGRect)frame 35 | { 36 | if (self = [super initWithFrame:frame]) { 37 | [self setUI]; 38 | } 39 | return self; 40 | } 41 | 42 | 43 | -(void)setUI 44 | { 45 | [super setUI]; 46 | topMargin = 10; //上面的距离 47 | bottomMargin = 10; //下面的距离 48 | leftMargin = 8; //最左边的距离 49 | colMargin = 2;//行间距 50 | rowMargin = 10;//列间距 51 | 52 | topBtnW = (Kwidth - 2 * leftMargin - 9 * colMargin) / 10; //按钮的宽度 53 | topBtnH = (keyBoardHeight - 5 * topMargin) * 0.25 ; //按钮的高度 54 | if (self.dataSource.count > 0) return ; 55 | NSString *string = @"1234567890QWERTYUIOPASDFGHJKLZXCVBNM"; 56 | 57 | for (int i = 0; i < string.length; i++) { 58 | NSString *str = [string substringWithRange:NSMakeRange(i, 1)]; 59 | [self.dataSource addObject:str]; 60 | UIButton *btn = [self creatNormalBtn]; 61 | [btn setTitle:str forState:UIControlStateNormal]; 62 | [btn setBackgroundImage :[self nomImage:YES] forState:UIControlStateNormal]; 63 | [btn setBackgroundImage :[self nomImage:NO] forState:UIControlStateHighlighted]; 64 | btn.tag = i + 1000 ; 65 | [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 66 | btn.backgroundColor = [UIColor clearColor]; 67 | [self addSubview:btn]; 68 | } 69 | [self addSubview:self.deleteBtn]; 70 | [self addSubview:self.switchBtn]; 71 | } 72 | 73 | #pragma mark 布局 74 | /** 布局 */ 75 | -(void)layoutSubviews 76 | { 77 | [super layoutSubviews]; 78 | [self wordlayout];//字母的布局 79 | [self specialBtnLayout];//特殊按钮的布局 删除,空格,退格,大小写切换等 80 | } 81 | 82 | /** 字母的布局 */ 83 | -(void)wordlayout 84 | { 85 | int i = 0 ; 86 | for (UIView *btn in self.subviews) { 87 | if (i == 36) { 88 | break; 89 | } 90 | CGFloat col = i % 10; 91 | if (i < 10){ 92 | //字母键盘第一排 10 个 93 | btn.x = leftMargin + col * (topBtnW + colMargin); 94 | btn.y = topMargin + 0 * (topBtnH + rowMargin); 95 | 96 | }else if (10 <= i && i <= 19 ) { 97 | //字母键盘第二排排 10 个 98 | btn.x = leftMargin + col * (topBtnW + colMargin); 99 | btn.y = topMargin + 1 * (topBtnH + rowMargin); 100 | 101 | }else if(i > 19 && i <= 28){ 102 | //字母第三排 103 | btn.x = leftMargin + topBtnW * 0.5 + colMargin * 0.5 + col * (topBtnW + colMargin); 104 | btn.y = topMargin + 2 * (topBtnH + rowMargin); 105 | }else{ 106 | //字母第四排 107 | col = col + 2; 108 | btn.x = leftMargin + topBtnW * 0.5 + colMargin * 0.5 + col * (topBtnW + colMargin); 109 | btn.y = topMargin + 3 * (topBtnH + rowMargin); 110 | if (i == 29) { 111 | btn.x = col + topBtnW * 0.5 + topBtnW; 112 | } 113 | } 114 | btn.width = topBtnW; 115 | btn.height = topBtnH; 116 | i++; 117 | } 118 | } 119 | 120 | -(void)specialBtnLayout 121 | { 122 | UIView *zBtn = [self viewWithTag:1000 + 35]; 123 | //退格按钮位置 124 | self.deleteBtn.x = CGRectGetMaxX(zBtn.frame) + colMargin; 125 | self.deleteBtn.width = topBtnW * 1.5 ; 126 | self.deleteBtn.height = topBtnH; 127 | self.deleteBtn.y = topMargin + 3 * (topBtnH + rowMargin); 128 | 129 | //切换数字和字母键盘 130 | self.switchBtn.x = leftMargin ; 131 | self.switchBtn.y = topMargin + 3 * (topBtnH + rowMargin); 132 | self.switchBtn.width = topBtnW * 1.5; 133 | self.switchBtn.height = topBtnH; 134 | } 135 | 136 | #pragma makr 内部方法 137 | /** 图片的拉伸 */ 138 | - (UIImage *)nomImage:(BOOL)isNom { 139 | 140 | /////获取bundle 里面的图片 141 | NSBundle *currenBundle = [NSBundle bundleForClass:[self class]]; 142 | if (isNom) { 143 | NSString *imagePath = [currenBundle pathForResource:@"c_chaKeyboardButton@2x.png" ofType:nil inDirectory:@"KeyBoardSource.Bundle"]; 144 | // 普通图片 145 | UIImage *image = [UIImage imageWithContentsOfFile:imagePath]; 146 | //部分拉升图片 147 | image = [image stretchableImageWithLeftCapWidth:image.size.width * 0.5 topCapHeight:image.size.height * 0.5]; 148 | return image; 149 | }else{ 150 | // 高亮图片 151 | NSString *imagePath = [currenBundle pathForResource:@"c_chaKeyboardButtonSel@2x.png" ofType:nil inDirectory:@"KeyBoardSource.Bundle"]; 152 | UIImage *highImage = [UIImage imageWithContentsOfFile:imagePath]; 153 | //部分拉升图片 154 | highImage = [highImage stretchableImageWithLeftCapWidth:highImage.size.width * 0.5 topCapHeight:highImage.size.height * 0.5]; 155 | return highImage; 156 | } 157 | } 158 | 159 | #pragma mark Lazy -----懒加载-------- 160 | -(SwitchBtn *)switchBtn 161 | { 162 | if (!_switchBtn) { 163 | _switchBtn = [self creatSwitchBtn]; 164 | _switchBtn.backgroundColor = [UIColor clearColor]; 165 | [_switchBtn setBackgroundImage:[self nomImage:NO] forState:UIControlStateNormal]; 166 | [_switchBtn setTitle:@"<-" forState:UIControlStateNormal]; 167 | _switchBtn.titleLabel.font = [UIFont systemFontOfSize:16]; 168 | _switchBtn.contentMode = UIViewContentModeCenter; 169 | } 170 | return _switchBtn; 171 | } 172 | -(DeleteBtn *)deleteBtn 173 | { 174 | if (!_deleteBtn) { 175 | _deleteBtn = [self creatDeleteBtn]; 176 | _deleteBtn.backgroundColor = [UIColor clearColor]; 177 | 178 | NSBundle *currenBundle = [NSBundle bundleForClass:[self class]]; 179 | NSString *deleteImagePath = [currenBundle pathForResource:@"c_character_keyboardDeleteButton@2x.png" ofType:nil inDirectory:@"KeyBoardSource.Bundle"]; 180 | NSString *deleteSelectmagePath = [currenBundle pathForResource:@"c_character_keyboardDeleteButtonSel@2x.png" ofType:nil inDirectory:@"KeyBoardSource.Bundle"]; 181 | 182 | UIImage *deleteImage = [UIImage imageWithContentsOfFile:deleteImagePath]; 183 | UIImage *deleteSelectxmImage = [UIImage imageWithContentsOfFile:deleteSelectmagePath]; 184 | 185 | [_deleteBtn setImage:deleteImage forState:UIControlStateNormal]; 186 | [_deleteBtn setImage:deleteSelectxmImage forState:UIControlStateHighlighted]; 187 | 188 | _deleteBtn.contentMode = UIViewContentModeCenter; 189 | } 190 | return _deleteBtn; 191 | } 192 | 193 | @end 194 | -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/CarNumHeaderKeyBoard/XMCarNumHeaderKeyBoard.h: -------------------------------------------------------------------------------- 1 | // 2 | // XMCarNumHeaderKeyBoard.h 3 | // XMTXCustomKeyBoard 4 | // 5 | // Created by 风吹裤衩 on 2018/11/13. 6 | // Copyright © 2018年 风吹裤衩. All rights reserved. 7 | // 8 | 9 | #import "XMBasekeyBoardView.h" 10 | 11 | @interface XMCarNumHeaderKeyBoard : XMBasekeyBoardView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/CarNumHeaderKeyBoard/XMCarNumHeaderKeyBoard.m: -------------------------------------------------------------------------------- 1 | // 2 | // XMCarNumHeaderKeyBoard.m 3 | // XMTXCustomKeyBoard 4 | // 5 | // Created by 风吹裤衩 on 2018/11/13. 6 | // Copyright © 2018年 风吹裤衩. All rights reserved. 7 | // 8 | 9 | #import "XMCarNumHeaderKeyBoard.h" 10 | 11 | @interface XMCarNumHeaderKeyBoard() 12 | { 13 | 14 | CGFloat topMargin ; //上面的距离 15 | CGFloat bottomMargin ; //下面的距离 16 | CGFloat leftMargin ; //最左边的距离 17 | CGFloat colMargin ;//行间距 18 | CGFloat rowMargin ;//列间距 19 | CGFloat topBtnW ; //按钮的宽度 20 | CGFloat topBtnH ; //按钮的高度 21 | } 22 | /** 装载切割好了的字符串 */ 23 | @property (nonatomic,strong)NSMutableArray *dataSource; 24 | /** 退格按钮 */ 25 | @property (nonatomic,strong)DeleteBtn *deleteBtn; 26 | 27 | /** 字符和数字的切换按钮 */ 28 | @property (nonatomic,strong)SwitchBtn *switchBtn; 29 | 30 | /** 隐藏按钮 */ 31 | @property (nonatomic,strong)HiddenBtn *hiddenBtn; 32 | 33 | @end 34 | 35 | @implementation XMCarNumHeaderKeyBoard 36 | 37 | 38 | -(instancetype)initWithFrame:(CGRect)frame 39 | { 40 | if (self = [super initWithFrame:frame]) { 41 | [self setUI]; 42 | } 43 | return self; 44 | } 45 | 46 | -(void)setUI 47 | { 48 | [super setUI]; 49 | 50 | topMargin = 10; //上面的距离 51 | bottomMargin = 10; //下面的距离 52 | leftMargin = 8; //最左边的距离 53 | colMargin = 2;//行间距 54 | rowMargin = 10;//列间距 55 | 56 | topBtnW = (Kwidth - 2 * leftMargin - 9 * colMargin) / 10; //按钮的宽度 57 | topBtnH = (keyBoardHeight - 5 * topMargin) * 0.25 ; //按钮的高度 58 | if (self.dataSource.count > 0) return ; 59 | NSString *string = @"京津晋冀蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼渝川贵云藏陕甘青宁新港澳学挂警"; 60 | 61 | for (int i = 0; i < string.length; i++) { 62 | NSString *str = [string substringWithRange:NSMakeRange(i, 1)]; 63 | [self.dataSource addObject:str]; 64 | UIButton *btn = [self creatNormalBtn]; 65 | [btn setTitle:str forState:UIControlStateNormal]; 66 | [btn setBackgroundImage :[self nomImage:YES] forState:UIControlStateNormal]; 67 | [btn setBackgroundImage :[self nomImage:NO] forState:UIControlStateHighlighted]; 68 | btn.tag = i + 1000 ; 69 | [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 70 | btn.backgroundColor = [UIColor clearColor]; 71 | [self addSubview:btn]; 72 | } 73 | 74 | [self addSubview:self.switchBtn]; 75 | [self addSubview:self.hiddenBtn]; 76 | [self addSubview:self.deleteBtn]; 77 | } 78 | 79 | #pragma mark 布局 80 | /** 布局 */ 81 | -(void)layoutSubviews 82 | { 83 | [super layoutSubviews]; 84 | [self wordlayout];//字母的布局 85 | [self specialBtnLayout];//特殊按钮的布局 删除,空格,退格,大小写切换等 86 | } 87 | 88 | /** 字母的布局 */ 89 | -(void)wordlayout 90 | { 91 | int i = 0 ; 92 | for (UIView *btn in self.subviews) { 93 | 94 | if (i ==36) { 95 | //// 这里是特殊按钮布局的,在 specialBtnLayout进行布局 96 | break; 97 | } 98 | 99 | CGFloat col = i % 10; 100 | if (i < 10){ 101 | //字母键盘第一排 10 个 102 | btn.x = leftMargin + col * (topBtnW + colMargin); 103 | btn.y = topMargin + 0 * (topBtnH + rowMargin); 104 | 105 | }else if (10 <= i && i <= 19 ) { 106 | //字母键盘第二排排 10 个 107 | btn.x = leftMargin + col * (topBtnW + colMargin); 108 | btn.y = topMargin + 1 * (topBtnH + rowMargin); 109 | 110 | }else if(i > 19 && i <= 29){ 111 | //字母第三排 112 | btn.x = leftMargin + col * (topBtnW + colMargin); 113 | btn.y = topMargin + 2 * (topBtnH + rowMargin); 114 | }else{ 115 | //字母第四排 116 | btn.x = leftMargin + col * (topBtnW + colMargin); 117 | btn.y = topMargin + 3 * (topBtnH + rowMargin); 118 | } 119 | btn.width = topBtnW; 120 | btn.height = topBtnH; 121 | i++; 122 | } 123 | } 124 | 125 | //** 特殊字符布局 */ 126 | -(void)specialBtnLayout 127 | { 128 | UIView *lastView = [self viewWithTag:35 + 1000]; 129 | CGFloat specialwidth = 4 * topBtnW / 3 ; 130 | CGFloat specialY = topMargin + 3 * (topBtnH + rowMargin) ; 131 | self.hiddenBtn.frame = CGRectMake(CGRectGetMaxX(lastView.frame) + colMargin, specialY, specialwidth, topBtnH); 132 | self.switchBtn.frame = CGRectMake(CGRectGetMaxX(self.hiddenBtn.frame) + colMargin, specialY, specialwidth, topBtnH); 133 | self.deleteBtn.frame = CGRectMake(CGRectGetMaxX(self.switchBtn.frame) + colMargin, specialY, specialwidth, topBtnH); 134 | } 135 | 136 | #pragma makr 内部方法 137 | /** 图片的拉伸 */ 138 | - (UIImage *)nomImage:(BOOL)isNom { 139 | 140 | /////获取bundle 里面的图片 141 | NSBundle *currenBundle = [NSBundle bundleForClass:[self class]]; 142 | if (isNom) { 143 | NSString *imagePath = [currenBundle pathForResource:@"c_chaKeyboardButton@2x.png" ofType:nil inDirectory:@"KeyBoardSource.Bundle"]; 144 | // 普通图片 145 | UIImage *image = [UIImage imageWithContentsOfFile:imagePath]; 146 | //部分拉升图片 147 | image = [image stretchableImageWithLeftCapWidth:image.size.width * 0.5 topCapHeight:image.size.height * 0.5]; 148 | return image; 149 | }else{ 150 | // 高亮图片 151 | NSString *imagePath = [currenBundle pathForResource:@"c_chaKeyboardButtonSel@2x.png" ofType:nil inDirectory:@"KeyBoardSource.Bundle"]; 152 | UIImage *highImage = [UIImage imageWithContentsOfFile:imagePath]; 153 | //部分拉升图片 154 | highImage = [highImage stretchableImageWithLeftCapWidth:highImage.size.width * 0.5 topCapHeight:highImage.size.height * 0.5]; 155 | return highImage; 156 | } 157 | } 158 | 159 | #pragma mark Lazy -----懒加载-------- 160 | -(SwitchBtn *)switchBtn 161 | { 162 | if (!_switchBtn) { 163 | _switchBtn = [self creatSwitchBtn]; 164 | _switchBtn.backgroundColor = [UIColor clearColor]; 165 | [_switchBtn setBackgroundImage:[self nomImage:NO] forState:UIControlStateNormal]; 166 | [_switchBtn setTitle:@"更多" forState:UIControlStateNormal]; 167 | _switchBtn.titleLabel.font = [UIFont systemFontOfSize:16]; 168 | _switchBtn.contentMode = UIViewContentModeCenter; 169 | } 170 | return _switchBtn; 171 | } 172 | -(DeleteBtn *)deleteBtn 173 | { 174 | if (!_deleteBtn) { 175 | _deleteBtn = [self creatDeleteBtn]; 176 | _deleteBtn.backgroundColor = [UIColor clearColor]; 177 | 178 | NSBundle *currenBundle = [NSBundle bundleForClass:[self class]]; 179 | NSString *deleteImagePath = [currenBundle pathForResource:@"c_character_keyboardDeleteButton@2x.png" ofType:nil inDirectory:@"KeyBoardSource.Bundle"]; 180 | NSString *deleteSelectmagePath = [currenBundle pathForResource:@"c_character_keyboardDeleteButtonSel@2x.png" ofType:nil inDirectory:@"KeyBoardSource.Bundle"]; 181 | 182 | UIImage *deleteImage = [UIImage imageWithContentsOfFile:deleteImagePath]; 183 | UIImage *deleteSelectxmImage = [UIImage imageWithContentsOfFile:deleteSelectmagePath]; 184 | 185 | [_deleteBtn setImage:deleteImage forState:UIControlStateNormal]; 186 | [_deleteBtn setImage:deleteSelectxmImage forState:UIControlStateHighlighted]; 187 | 188 | _deleteBtn.contentMode = UIViewContentModeCenter; 189 | } 190 | return _deleteBtn; 191 | } 192 | 193 | 194 | -(HiddenBtn *)hiddenBtn 195 | { 196 | if (!_hiddenBtn) { 197 | _hiddenBtn = [self creatHiddenBtn]; 198 | _hiddenBtn.backgroundColor = [UIColor clearColor]; 199 | [_hiddenBtn setBackgroundImage:[self nomImage:NO] forState:UIControlStateNormal]; 200 | [_hiddenBtn setBackgroundImage:[self nomImage:YES] forState:UIControlStateHighlighted]; 201 | _hiddenBtn.contentMode = UIViewContentModeCenter; 202 | [_hiddenBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 203 | [_hiddenBtn setTitle:@"隐藏" forState:UIControlStateNormal]; 204 | } 205 | return _hiddenBtn; 206 | } 207 | 208 | 209 | @end 210 | -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/CharKeyBoard/XMCharKeyBoardView.h: -------------------------------------------------------------------------------- 1 | // 2 | // XMCharKeyBoardView.h 3 | // XMTXCustomKeyBoard 4 | // 5 | // Created by 风吹裤衩 on 2018/11/12. 6 | // Copyright © 2018年 风吹裤衩. All rights reserved. 7 | // 8 | 9 | #import "XMBasekeyBoardView.h" 10 | 11 | /** 12 | 字符键盘 13 | */ 14 | @interface XMCharKeyBoardView : XMBasekeyBoardView 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/CharKeyBoard/XMCharKeyBoardView.m: -------------------------------------------------------------------------------- 1 | // 2 | // XMCharKeyBoardView.m 3 | // XMTXCustomKeyBoard 4 | // 5 | // Created by 风吹裤衩 on 2018/11/12. 6 | // Copyright © 2018年 风吹裤衩. All rights reserved. 7 | // 8 | 9 | #import "XMCharKeyBoardView.h" 10 | 11 | 12 | @interface XMCharKeyBoardView() 13 | { 14 | 15 | CGFloat topMargin ; //上面的距离 16 | CGFloat bottomMargin ; //下面的距离 17 | CGFloat leftMargin ; //最左边的距离 18 | CGFloat colMargin ;//行间距 19 | CGFloat rowMargin ;//列间距 20 | CGFloat topBtnW ; //按钮的宽度 21 | CGFloat topBtnH ; //按钮的高度 22 | } 23 | /** 装载切割好了的字符串 */ 24 | @property (nonatomic,strong)NSMutableArray *dataSource; 25 | /** 退格按钮 */ 26 | @property (nonatomic,strong)DeleteBtn *deleteBtn; 27 | /** 确定按钮 */ 28 | @property (nonatomic,strong)DetermineBtn *determinBtn; 29 | /** 空格按钮 */ 30 | @property (nonatomic,strong)SpaceBtn *spaceBtn; 31 | /** 字符和数字的切换按钮 */ 32 | @property (nonatomic,strong)SwitchBtn *switchBtn; 33 | /** 数字和拼音的切换按钮 */ 34 | @property (nonatomic,strong)SwitchBtn *switchBtnPy; 35 | /** 隐藏按钮 */ 36 | @property (nonatomic,strong)HiddenBtn *hiddenBtn; 37 | 38 | @end 39 | 40 | @implementation XMCharKeyBoardView 41 | 42 | -(instancetype)initWithFrame:(CGRect)frame 43 | { 44 | if (self = [super initWithFrame:frame]) { 45 | [self setUI]; 46 | } 47 | return self; 48 | } 49 | 50 | -(void)setUI 51 | { 52 | [super setUI]; 53 | 54 | topMargin = 10; //上面的距离 55 | bottomMargin = 10; //下面的距离 56 | leftMargin = 8; //最左边的距离 57 | colMargin = 2;//行间距 58 | rowMargin = 10;//列间距 59 | 60 | topBtnW = (Kwidth - 2 * leftMargin - 9 * colMargin) / 10; //按钮的宽度 61 | topBtnH = (keyBoardHeight - 5 * topMargin) * 0.25 ; //按钮的高度 62 | if (self.dataSource.count > 0) return ; 63 | NSString *string = @"1234567890-+*/:;()¥@“”。,、?!."; 64 | 65 | for (int i = 0; i < string.length; i++) { 66 | NSString *str = [string substringWithRange:NSMakeRange(i, 1)]; 67 | [self.dataSource addObject:str]; 68 | UIButton *btn = [self creatNormalBtn]; 69 | [btn setTitle:str forState:UIControlStateNormal]; 70 | [btn setBackgroundImage :[self nomImage:YES] forState:UIControlStateNormal]; 71 | [btn setBackgroundImage :[self nomImage:NO] forState:UIControlStateHighlighted]; 72 | btn.tag = i + 1000 ; 73 | [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 74 | btn.backgroundColor = [UIColor clearColor]; 75 | [self addSubview:btn]; 76 | } 77 | 78 | [self addSubview:self.switchBtn]; 79 | [self addSubview:self.deleteBtn]; 80 | [self addSubview:self.switchBtnPy]; 81 | [self addSubview:self.spaceBtn]; 82 | [self addSubview:self.determinBtn]; 83 | [self addSubview:self.hiddenBtn]; 84 | } 85 | 86 | #pragma mark 布局 87 | /** 布局 */ 88 | -(void)layoutSubviews 89 | { 90 | [super layoutSubviews]; 91 | [self wordlayout];//字母的布局 92 | [self specialBtnLayout];//特殊按钮的布局 删除,空格,退格,大小写切换等 93 | } 94 | 95 | 96 | /** 字母的布局 */ 97 | -(void)wordlayout 98 | { 99 | int i = 0 ; 100 | for (UIView *btn in self.subviews) { 101 | CGFloat col = i % 10; 102 | if (i < 10){ 103 | //字母键盘第一排 10 个 104 | btn.x = leftMargin + col * (topBtnW + colMargin); 105 | btn.y = topMargin + 0 * (topBtnH + rowMargin); 106 | 107 | }else if (10 <= i && i <= 19 ) { 108 | //字母键盘第二排排 10 个 109 | btn.x = leftMargin + col * (topBtnW + colMargin); 110 | btn.y = topMargin + 1 * (topBtnH + rowMargin); 111 | 112 | }else if(i > 19){ 113 | //字母第三排 114 | btn.x = leftMargin + topBtnW + colMargin + col * (topBtnW + colMargin); 115 | btn.y = topMargin + 2 * (topBtnH + rowMargin); 116 | } 117 | btn.width = topBtnW; 118 | btn.height = topBtnH; 119 | i++; 120 | } 121 | } 122 | 123 | -(void)specialBtnLayout 124 | { 125 | //大小写切换按钮位置 126 | self.switchBtn.x = leftMargin ; 127 | self.switchBtn.width = topBtnW ; 128 | self.switchBtn.height = topBtnH; 129 | self.switchBtn.y = topMargin + 2 * (topBtnH + rowMargin); 130 | 131 | UIView *zBtn = [self viewWithTag:1000 + 27]; 132 | //退格按钮位置 133 | self.deleteBtn.x = CGRectGetMaxX(zBtn.frame) + colMargin; 134 | self.deleteBtn.width = topBtnW ; 135 | self.deleteBtn.height = topBtnH; 136 | self.deleteBtn.y = topMargin + 2 * (topBtnH + rowMargin); 137 | 138 | 139 | //切换数字和字母键盘 140 | self.switchBtnPy.x = leftMargin ; 141 | self.switchBtnPy.y = topMargin + 3 * (topBtnH + rowMargin); 142 | self.switchBtnPy.width = topBtnW * 1.5; 143 | self.switchBtnPy.height = topBtnH; 144 | 145 | //隐藏按钮布局 146 | self.hiddenBtn.x = CGRectGetMaxX(self.switchBtnPy.frame) + colMargin; 147 | self.hiddenBtn.y = topMargin + 3 * (topBtnH + rowMargin); 148 | self.hiddenBtn.width = topBtnW * 1.5; 149 | self.hiddenBtn.height = topBtnH; 150 | 151 | //空格按钮布局 152 | self.spaceBtn.x = CGRectGetMaxX(self.hiddenBtn.frame) + colMargin; 153 | self.spaceBtn.y = topMargin + 3 * (topBtnH + rowMargin); 154 | self.spaceBtn.width = 4.5 * topBtnW + 4 * colMargin; 155 | self.spaceBtn.height = topBtnH; 156 | 157 | //确定按钮 158 | self.determinBtn.x = CGRectGetMaxX(self.spaceBtn.frame) + colMargin; 159 | self.determinBtn.y = topMargin + 3 * (topBtnH + rowMargin); 160 | self.determinBtn.width = CGRectGetMaxX(self.deleteBtn.frame) - CGRectGetMaxX(self.spaceBtn.frame) + colMargin; 161 | self.determinBtn.height = topBtnH; 162 | } 163 | 164 | #pragma makr 内部方法 165 | /** 图片的拉伸 */ 166 | - (UIImage *)nomImage:(BOOL)isNom { 167 | 168 | /////获取bundle 里面的图片 169 | NSBundle *currenBundle = [NSBundle bundleForClass:[self class]]; 170 | if (isNom) { 171 | NSString *imagePath = [currenBundle pathForResource:@"c_chaKeyboardButton@2x.png" ofType:nil inDirectory:@"KeyBoardSource.Bundle"]; 172 | // 普通图片 173 | UIImage *image = [UIImage imageWithContentsOfFile:imagePath]; 174 | //部分拉升图片 175 | image = [image stretchableImageWithLeftCapWidth:image.size.width * 0.5 topCapHeight:image.size.height * 0.5]; 176 | return image; 177 | }else{ 178 | // 高亮图片 179 | NSString *imagePath = [currenBundle pathForResource:@"c_chaKeyboardButtonSel@2x.png" ofType:nil inDirectory:@"KeyBoardSource.Bundle"]; 180 | UIImage *highImage = [UIImage imageWithContentsOfFile:imagePath]; 181 | //部分拉升图片 182 | highImage = [highImage stretchableImageWithLeftCapWidth:highImage.size.width * 0.5 topCapHeight:highImage.size.height * 0.5]; 183 | return highImage; 184 | } 185 | } 186 | 187 | #pragma mark Lazy -----懒加载-------- 188 | -(SwitchBtn *)switchBtn 189 | { 190 | if (!_switchBtn) { 191 | _switchBtn = [self creatSwitchBtn]; 192 | _switchBtn.backgroundColor = [UIColor clearColor]; 193 | [_switchBtn setBackgroundImage:[self nomImage:NO] forState:UIControlStateNormal]; 194 | [_switchBtn setTitle:@"123" forState:UIControlStateNormal]; 195 | _switchBtn.titleLabel.font = [UIFont systemFontOfSize:16]; 196 | _switchBtn.contentMode = UIViewContentModeCenter; 197 | } 198 | return _switchBtn; 199 | } 200 | -(DeleteBtn *)deleteBtn 201 | { 202 | if (!_deleteBtn) { 203 | _deleteBtn = [self creatDeleteBtn]; 204 | _deleteBtn.backgroundColor = [UIColor clearColor]; 205 | 206 | NSBundle *currenBundle = [NSBundle bundleForClass:[self class]]; 207 | NSString *deleteImagePath = [currenBundle pathForResource:@"c_character_keyboardDeleteButton@2x.png" ofType:nil inDirectory:@"KeyBoardSource.Bundle"]; 208 | NSString *deleteSelectmagePath = [currenBundle pathForResource:@"c_character_keyboardDeleteButtonSel@2x.png" ofType:nil inDirectory:@"KeyBoardSource.Bundle"]; 209 | 210 | UIImage *deleteImage = [UIImage imageWithContentsOfFile:deleteImagePath]; 211 | UIImage *deleteSelectxmImage = [UIImage imageWithContentsOfFile:deleteSelectmagePath]; 212 | 213 | [_deleteBtn setImage:deleteImage forState:UIControlStateNormal]; 214 | [_deleteBtn setImage:deleteSelectxmImage forState:UIControlStateHighlighted]; 215 | 216 | _deleteBtn.contentMode = UIViewContentModeCenter; 217 | } 218 | return _deleteBtn; 219 | } 220 | 221 | 222 | -(HiddenBtn *)hiddenBtn 223 | { 224 | if (!_hiddenBtn) { 225 | _hiddenBtn = [self creatHiddenBtn]; 226 | _hiddenBtn.backgroundColor = [UIColor clearColor]; 227 | [_hiddenBtn setBackgroundImage:[self nomImage:NO] forState:UIControlStateNormal]; 228 | [_hiddenBtn setBackgroundImage:[self nomImage:YES] forState:UIControlStateHighlighted]; 229 | _hiddenBtn.contentMode = UIViewContentModeCenter; 230 | [_hiddenBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 231 | [_hiddenBtn setTitle:@"隐藏" forState:UIControlStateNormal]; 232 | } 233 | return _hiddenBtn; 234 | } 235 | 236 | -(SpaceBtn *)spaceBtn 237 | { 238 | if (!_spaceBtn) { 239 | _spaceBtn = [self creatSpaceBtn]; 240 | _spaceBtn.backgroundColor = [UIColor clearColor]; 241 | 242 | [_spaceBtn setBackgroundImage:[self nomImage:NO] forState:UIControlStateNormal]; 243 | [_spaceBtn setBackgroundImage:[self nomImage:YES] forState:UIControlStateHighlighted]; 244 | [_spaceBtn setTitle:@"空格" forState:UIControlStateNormal]; 245 | [_spaceBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 246 | _spaceBtn.contentMode = UIViewContentModeCenter; 247 | } 248 | return _spaceBtn; 249 | } 250 | 251 | -(SwitchBtn *)switchBtnPy 252 | { 253 | if (!_switchBtnPy) { 254 | _switchBtnPy = [self creatSwitchBtn]; 255 | _switchBtnPy.backgroundColor = [UIColor clearColor]; 256 | 257 | [_switchBtnPy setBackgroundImage:[self nomImage:NO] forState:UIControlStateNormal]; 258 | [_switchBtnPy setBackgroundImage:[self nomImage:YES] forState:UIControlStateHighlighted]; 259 | [_switchBtnPy setTitle:@"拼音" forState:UIControlStateNormal]; 260 | [_switchBtnPy setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 261 | _switchBtnPy.contentMode = UIViewContentModeCenter; 262 | } 263 | return _switchBtnPy; 264 | } 265 | 266 | -(DetermineBtn *)determinBtn 267 | { 268 | if (!_determinBtn) { 269 | _determinBtn = [self creatDetermineBtnBtn]; 270 | _determinBtn.backgroundColor = [UIColor clearColor]; 271 | 272 | [_determinBtn setBackgroundImage:[self nomImage:NO] forState:UIControlStateNormal]; 273 | [_determinBtn setBackgroundImage:[self nomImage:YES] forState:UIControlStateHighlighted]; 274 | [_determinBtn setTitle:@"确定" forState:UIControlStateNormal]; 275 | [_determinBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 276 | _determinBtn.contentMode = UIViewContentModeCenter; 277 | } 278 | return _determinBtn; 279 | } 280 | 281 | @end 282 | -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/KeyBoardSource.Bundle/CXXshift@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgmsuccess/CustomKeyBoard/54c1482eec44653cd4b87b4383686379977d3d15/Classes/CXXkeyBoard/KeyBoardSource.Bundle/CXXshift@2x.png -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_chaKeyboardButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgmsuccess/CustomKeyBoard/54c1482eec44653cd4b87b4383686379977d3d15/Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_chaKeyboardButton.png -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_chaKeyboardButton@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgmsuccess/CustomKeyBoard/54c1482eec44653cd4b87b4383686379977d3d15/Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_chaKeyboardButton@2x.png -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_chaKeyboardButtonSel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgmsuccess/CustomKeyBoard/54c1482eec44653cd4b87b4383686379977d3d15/Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_chaKeyboardButtonSel.png -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_chaKeyboardButtonSel@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgmsuccess/CustomKeyBoard/54c1482eec44653cd4b87b4383686379977d3d15/Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_chaKeyboardButtonSel@2x.png -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_chaKeyboardShiftButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgmsuccess/CustomKeyBoard/54c1482eec44653cd4b87b4383686379977d3d15/Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_chaKeyboardShiftButton.png -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_chaKeyboardShiftButton@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgmsuccess/CustomKeyBoard/54c1482eec44653cd4b87b4383686379977d3d15/Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_chaKeyboardShiftButton@2x.png -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_chaKeyboardShiftButtonSel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgmsuccess/CustomKeyBoard/54c1482eec44653cd4b87b4383686379977d3d15/Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_chaKeyboardShiftButtonSel.png -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_chaKeyboardShiftButtonSel@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgmsuccess/CustomKeyBoard/54c1482eec44653cd4b87b4383686379977d3d15/Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_chaKeyboardShiftButtonSel@2x.png -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_character_keyboardDeleteButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgmsuccess/CustomKeyBoard/54c1482eec44653cd4b87b4383686379977d3d15/Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_character_keyboardDeleteButton.png -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_character_keyboardDeleteButton@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgmsuccess/CustomKeyBoard/54c1482eec44653cd4b87b4383686379977d3d15/Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_character_keyboardDeleteButton@2x.png -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_character_keyboardDeleteButtonSel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgmsuccess/CustomKeyBoard/54c1482eec44653cd4b87b4383686379977d3d15/Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_character_keyboardDeleteButtonSel.png -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_character_keyboardDeleteButtonSel@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgmsuccess/CustomKeyBoard/54c1482eec44653cd4b87b4383686379977d3d15/Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_character_keyboardDeleteButtonSel@2x.png -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_character_keyboardSwitchButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgmsuccess/CustomKeyBoard/54c1482eec44653cd4b87b4383686379977d3d15/Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_character_keyboardSwitchButton.png -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_character_keyboardSwitchButton@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgmsuccess/CustomKeyBoard/54c1482eec44653cd4b87b4383686379977d3d15/Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_character_keyboardSwitchButton@2x.png -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_character_keyboardSwitchButtonSel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgmsuccess/CustomKeyBoard/54c1482eec44653cd4b87b4383686379977d3d15/Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_character_keyboardSwitchButtonSel.png -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_character_keyboardSwitchButtonSel@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgmsuccess/CustomKeyBoard/54c1482eec44653cd4b87b4383686379977d3d15/Classes/CXXkeyBoard/KeyBoardSource.Bundle/c_character_keyboardSwitchButtonSel@2x.png -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/KeyBoardSource.Bundle/emoji_touch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgmsuccess/CustomKeyBoard/54c1482eec44653cd4b87b4383686379977d3d15/Classes/CXXkeyBoard/KeyBoardSource.Bundle/emoji_touch.png -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/KeyBoardSource.Bundle/emoji_touch@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgmsuccess/CustomKeyBoard/54c1482eec44653cd4b87b4383686379977d3d15/Classes/CXXkeyBoard/KeyBoardSource.Bundle/emoji_touch@2x.png -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/KeyBoardSource.Bundle/newcapsLock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgmsuccess/CustomKeyBoard/54c1482eec44653cd4b87b4383686379977d3d15/Classes/CXXkeyBoard/KeyBoardSource.Bundle/newcapsLock.png -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/KeyBoardSource.Bundle/newcapsLock@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgmsuccess/CustomKeyBoard/54c1482eec44653cd4b87b4383686379977d3d15/Classes/CXXkeyBoard/KeyBoardSource.Bundle/newcapsLock@2x.png -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/KeyBoardSource.Bundle/newcapsLock@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgmsuccess/CustomKeyBoard/54c1482eec44653cd4b87b4383686379977d3d15/Classes/CXXkeyBoard/KeyBoardSource.Bundle/newcapsLock@3x.png -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/KeyBoardSource.Bundle/newdelete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgmsuccess/CustomKeyBoard/54c1482eec44653cd4b87b4383686379977d3d15/Classes/CXXkeyBoard/KeyBoardSource.Bundle/newdelete.png -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/KeyBoardSource.Bundle/newdelete@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgmsuccess/CustomKeyBoard/54c1482eec44653cd4b87b4383686379977d3d15/Classes/CXXkeyBoard/KeyBoardSource.Bundle/newdelete@2x.png -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/KeyBoardSource.Bundle/newdelete@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgmsuccess/CustomKeyBoard/54c1482eec44653cd4b87b4383686379977d3d15/Classes/CXXkeyBoard/KeyBoardSource.Bundle/newdelete@3x.png -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/NumKeyBoardStyleOne/XMNumberKeyBoardStyleOne.h: -------------------------------------------------------------------------------- 1 | // 2 | // XMNumberKeyBoardStyleOne.h 3 | // XMTXCustomKeyBoard 4 | // 5 | // Created by 风吹裤衩 on 2018/11/11. 6 | // Copyright © 2018年 风吹裤衩. All rights reserved. 7 | // 8 | 9 | #import "XMBasekeyBoardView.h" 10 | 11 | /** 12 | 数字键盘 13 | */ 14 | @interface XMNumberKeyBoardStyleOne : XMBasekeyBoardView 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/NumKeyBoardStyleOne/XMNumberKeyBoardStyleOne.m: -------------------------------------------------------------------------------- 1 | // 2 | // XMNumberKeyBoardStyleOne.m 3 | // XMTXCustomKeyBoard 4 | // 5 | // Created by 风吹裤衩 on 2018/11/11. 6 | // Copyright © 2018年 风吹裤衩. All rights reserved. 7 | // 8 | 9 | #import "XMNumberKeyBoardStyleOne.h" 10 | 11 | @interface XMNumberKeyBoardStyleOne() 12 | 13 | //注释:- 退格 14 | @property (nonatomic,strong)DeleteBtn *deleteBtn ; 15 | 16 | //注释:- 确定 17 | @property (nonatomic,strong)DetermineBtn *determineBtn ; 18 | 19 | @end 20 | 21 | @implementation XMNumberKeyBoardStyleOne 22 | 23 | 24 | -(instancetype)initWithFrame:(CGRect)frame 25 | { 26 | if (self = [super initWithFrame:frame]) { 27 | [self setUI]; 28 | } 29 | return self; 30 | } 31 | 32 | -(void)setUI 33 | { 34 | [super setUI]; 35 | NSMutableArray *dataSource = @[@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"",@"0",@"."].mutableCopy; 36 | for (int i = 0; i < dataSource.count; i++) { 37 | NSString *str = dataSource[i]; 38 | UIButton *btn; 39 | btn = [self creatNormalBtn]; 40 | [btn setTitle:str forState:UIControlStateNormal]; 41 | [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 42 | btn.layer.borderWidth = 0.25; 43 | btn.layer.borderColor = keyBoardBackviewcolor.CGColor; 44 | [self addSubview:btn]; 45 | } 46 | [self addSubview:self.determineBtn]; 47 | [self addSubview:self.deleteBtn]; 48 | } 49 | 50 | -(void)layoutSubviews 51 | { 52 | [super layoutSubviews]; 53 | ///删除和确定按钮宽度 54 | CGFloat deleteWidth = Kwidth / 4 * 1.15; 55 | ///普通按钮的宽度 56 | CGFloat normalWidth = (Kwidth - deleteWidth) / 3; 57 | CGFloat normlbtnH = keyBoardHeight / XM_EmotionMaxRows; 58 | 59 | int i = 0 ; 60 | for (UIView *btn in self.subviews) { 61 | if (i >= self.subviews.count - 2) { 62 | break; 63 | } 64 | 65 | btn.width = normalWidth; 66 | btn.height = normlbtnH; 67 | btn.x = (i % 3) * normalWidth; 68 | btn.y = i / 3 * normlbtnH; 69 | i ++ ; 70 | } 71 | UIView *btn = self.subviews[2]; 72 | self.deleteBtn.frame = CGRectMake(CGRectGetMaxX(btn.frame), 0, deleteWidth, normlbtnH * 2); 73 | self.determineBtn.frame = CGRectMake(CGRectGetMaxX(btn.frame), CGRectGetMaxY(self.deleteBtn.frame), deleteWidth, normlbtnH * 2); 74 | } 75 | 76 | #pragma mark lazy 77 | 78 | -(DeleteBtn *)deleteBtn 79 | { 80 | if (!_deleteBtn) { 81 | NSBundle *currenBundle = [NSBundle bundleForClass:[self class]]; 82 | NSString *normalImagePath = [currenBundle pathForResource:@"newdelete@2x.png" ofType:nil inDirectory:@"KeyBoardSource.Bundle"]; 83 | UIImage *image = [UIImage imageWithContentsOfFile:normalImagePath]; 84 | _deleteBtn = [self creatDeleteBtn]; 85 | [_deleteBtn setImage:image forState:UIControlStateNormal]; 86 | _deleteBtn.layer.borderWidth = 0.25; 87 | _deleteBtn.layer.borderColor = keyBoardBackviewcolor.CGColor; 88 | } 89 | return _deleteBtn; 90 | } 91 | 92 | -(DetermineBtn *)determineBtn 93 | { 94 | if (!_determineBtn) { 95 | _determineBtn = [self creatDetermineBtnBtn]; 96 | [_determineBtn setTitle:@"确定" forState:UIControlStateNormal]; 97 | [_determineBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 98 | _determineBtn.backgroundColor = Color(117, 175, 239, 1); 99 | _determineBtn.layer.borderWidth = 0.25; 100 | _determineBtn.layer.borderColor = keyBoardBackviewcolor.CGColor; 101 | } 102 | return _determineBtn; 103 | } 104 | 105 | @end 106 | -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/NumKeyboard/XMNumberkeyBoard.h: -------------------------------------------------------------------------------- 1 | // 2 | // XMNumberkeyBoard.h 3 | // chexiaoxi 4 | // 5 | // Created by 风吹裤衩 on 2018/6/29. 6 | // Copyright © 2018年 风吹裤衩. All rights reserved. 7 | // 8 | 9 | #import "XMBasekeyBoardView.h" 10 | 11 | @interface XMNumberkeyBoard : XMBasekeyBoardView 12 | 13 | /** 初始化普通键盘 */ 14 | -(instancetype)initWithFrame:(CGRect)frame; 15 | 16 | /** 初始化随机键盘 */ 17 | -(instancetype)initWithFrameRandom:(CGRect)frame ; 18 | 19 | /** 初始化身份证键盘 */ 20 | -(instancetype)initWithIDCard:(CGRect)frame ;; 21 | 22 | /** 初始化纯数字的键盘 */ 23 | -(instancetype)initWithOnlyKeyBoard:(CGRect)frame ;; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/NumKeyboard/XMNumberkeyBoard.m: -------------------------------------------------------------------------------- 1 | // 2 | // XMNumberkeyBoard.m 3 | // chexiaoxi 4 | // 5 | // Created by 风吹裤衩 on 2018/6/29. 6 | // Copyright © 2018年 风吹裤衩. All rights reserved. 7 | // 8 | 9 | #import "XMNumberkeyBoard.h" 10 | 11 | 12 | 13 | @interface XMNumberkeyBoard() 14 | 15 | @property (nonatomic,strong)NSArray *dataSource; 16 | 17 | //注释:- 身份证 18 | @property (nonatomic,strong)NSArray *cardDataSource; 19 | 20 | @property (nonatomic,strong)NSArray *onlyNumberSopurce ; ///<纯数字键盘 21 | 22 | @end 23 | 24 | 25 | @implementation XMNumberkeyBoard 26 | 27 | -(instancetype)init 28 | { 29 | if (self = [super init]) { 30 | [self setUI]; 31 | } 32 | return self; 33 | } 34 | 35 | /** 初始化普通键盘 */ 36 | -(instancetype)initWithCoder:(NSCoder *)aDecoder 37 | { 38 | if (self = [super initWithCoder:aDecoder]) { 39 | [self setUI]; 40 | } 41 | return self; 42 | } 43 | 44 | /** 初始化普通键盘 */ 45 | -(instancetype)initWithFrame:(CGRect)frame 46 | { 47 | if (self = [super initWithFrame:frame]) { 48 | [self setUI]; 49 | } 50 | return self; 51 | } 52 | 53 | /** 随机键盘。暂时不支持xib创建 */ 54 | -(instancetype)initWithFrameRandom:(CGRect)frame 55 | { 56 | if (self = [super initWithFrame:frame]) { 57 | [self setRandomUI]; 58 | } 59 | return self; 60 | } 61 | 62 | -(instancetype)initWithOnlyKeyBoard:(CGRect)frame 63 | { 64 | if (self = [super initWithFrame:frame]) { 65 | [self setOnlyNumberUI]; 66 | 67 | } 68 | return self; 69 | } 70 | 71 | 72 | -(instancetype)initWithIDCard:(CGRect)frame 73 | { 74 | if (self = [super initWithFrame:frame]) { 75 | [self setIDcardUI]; 76 | } 77 | return self; 78 | } 79 | 80 | //** 纯数字键盘 */ 81 | -(void)setOnlyNumberUI 82 | { 83 | int i = 0; 84 | UIButton *numBtn; 85 | self.backgroundColor = keyBoardBackviewcolor; 86 | for (NSString *string in self.onlyNumberSopurce) { 87 | if (i == 3) { //退格 88 | numBtn = [self creatDeleteBtn]; 89 | }else if(i == 7){ //清空 90 | numBtn = [self creatClearBtn]; 91 | }else if(i == 11){ //隐藏 92 | numBtn = [self creatHiddenBtn]; 93 | }else if(i == 15){ // 确定 94 | numBtn = [self creatDetermineBtnBtn]; 95 | }else{ 96 | numBtn = [self creatNormalBtn]; //普通按钮 97 | } 98 | [numBtn setTitle:string forState:UIControlStateNormal]; 99 | numBtn.tag = 1000 + i; 100 | i++; 101 | numBtn.titleLabel.font = [UIFont systemFontOfSize:18]; 102 | numBtn.layer.borderWidth = 0.25; 103 | numBtn.layer.borderColor = keyBoardBtnColor.CGColor; 104 | [self addSubview:numBtn]; 105 | } 106 | 107 | } 108 | 109 | /** 设置身份证键盘 */ 110 | -(void)setIDcardUI 111 | { 112 | int i = 0; 113 | UIButton *numBtn; 114 | self.backgroundColor = keyBoardBackviewcolor; 115 | for (NSString *string in self.cardDataSource) { 116 | if (i == 3) { //退格 117 | numBtn = [self creatDeleteBtn]; 118 | }else if(i == 7){ //清空 119 | numBtn = [self creatClearBtn]; 120 | }else if(i == 11){ //隐藏 121 | numBtn = [self creatHiddenBtn]; 122 | }else if(i == 15){ // 确定 123 | numBtn = [self creatDetermineBtnBtn]; 124 | }else{ 125 | numBtn = [self creatNormalBtn]; //普通按钮 126 | } 127 | [numBtn setTitle:string forState:UIControlStateNormal]; 128 | numBtn.tag = 1000 + i; 129 | i++; 130 | numBtn.titleLabel.font = [UIFont systemFontOfSize:18]; 131 | numBtn.layer.borderWidth = 0.25; 132 | numBtn.layer.borderColor = keyBoardBtnColor.CGColor; 133 | [self addSubview:numBtn]; 134 | } 135 | } 136 | 137 | /** 随机键盘 */ 138 | -(void)setRandomUI 139 | { 140 | int i = 0; 141 | UIButton *numBtn; 142 | self.backgroundColor = keyBoardBackviewcolor; 143 | for (NSString *string in self.randomArr) { 144 | if (i == 3) { //退格 145 | numBtn = [self creatDeleteBtn]; 146 | }else if(i == 7){ //清空 147 | numBtn = [self creatClearBtn]; 148 | }else if(i == 11){ //隐藏 149 | numBtn = [self creatHiddenBtn]; 150 | }else if(i == 12){ //切换abc 151 | numBtn = [self creatSwitchBtn]; 152 | }else if(i == 15){ // 确定 153 | numBtn = [self creatDetermineBtnBtn]; 154 | }else{ 155 | numBtn = [self creatNormalBtn]; //普通按钮 156 | } 157 | [numBtn setTitle:string forState:UIControlStateNormal]; 158 | numBtn.tag = 1000 + i; 159 | i++; 160 | numBtn.titleLabel.font = [UIFont systemFontOfSize:18]; 161 | numBtn.layer.borderWidth = 0.25; 162 | numBtn.layer.borderColor = keyBoardBtnColor.CGColor; 163 | [self addSubview:numBtn]; 164 | } 165 | } 166 | 167 | /** 普通的数字键盘 */ 168 | -(void)setUI 169 | { 170 | [super setUI]; 171 | if (self.subviews.count > 0) return; 172 | 173 | int i = 0; 174 | UIButton *numBtn; 175 | 176 | for (NSString *string in self.dataSource) { 177 | if (i == 3) { //退格 178 | numBtn = [self creatDeleteBtn]; 179 | }else if(i == 7){ //清空 180 | numBtn = [self creatClearBtn]; 181 | }else if(i == 11){ //隐藏 182 | numBtn = [self creatHiddenBtn]; 183 | }else if(i == 12){ //切换abc 184 | numBtn = [self creatSwitchBtn]; 185 | }else if(i == 15){ // 确定 186 | numBtn = [self creatDetermineBtnBtn]; 187 | }else{ 188 | numBtn = [self creatNormalBtn]; //普通按钮 189 | } 190 | [numBtn setTitle:string forState:UIControlStateNormal]; 191 | numBtn.tag = 1000 + i; 192 | i++; 193 | 194 | numBtn.layer.borderWidth = 0.25; 195 | numBtn.layer.borderColor = keyBoardBackviewcolor.CGColor; 196 | [self addSubview:numBtn]; 197 | } 198 | } 199 | 200 | -(void)layoutSubviews 201 | { 202 | [super layoutSubviews]; 203 | CGFloat btnW = self.width / XM_EmotionMaxCols; 204 | CGFloat btnH = keyBoardHeight / XM_EmotionMaxRows; 205 | int i = 0 ; 206 | for (UIView *subView in self.subviews) { 207 | subView.width = btnW; 208 | subView.height = btnH; 209 | subView.x = (i%XM_EmotionMaxCols) * btnW; 210 | subView.y = (i/XM_EmotionMaxCols) * btnH; 211 | i++; 212 | } 213 | } 214 | 215 | #pragma mark Lazy 216 | 217 | //** 数字键盘 */ 218 | -(NSArray *)dataSource 219 | { 220 | if (!_dataSource) { 221 | _dataSource = @[@"1",@"2",@"3",@"退格",@"4",@"5",@"6",@"清空",@"7",@"8",@"9",@"隐藏",@"ABC",@"0",@".",@"确定"]; 222 | } 223 | return _dataSource; 224 | } 225 | 226 | //** 身份证键盘 */ 227 | -(NSArray *)cardDataSource 228 | { 229 | if (!_cardDataSource) { 230 | _cardDataSource = @[@"1",@"2",@"3",@"退格",@"4",@"5",@"6",@"清空",@"7",@"8",@"9",@"隐藏",@"X",@"0",@".",@"确定"]; 231 | } 232 | return _cardDataSource; 233 | } 234 | 235 | //** 纯数字键盘 */ 236 | -(NSArray *)onlyNumberSopurce{ 237 | if (!_onlyNumberSopurce) { 238 | _onlyNumberSopurce = @[@"1",@"2",@"3",@"退格",@"4",@"5",@"6",@"清空",@"7",@"8",@"9",@"隐藏",@"",@"0",@".",@"确定"]; 239 | } 240 | return _onlyNumberSopurce; 241 | } 242 | 243 | //插入特殊文字 244 | -(NSMutableArray *)randomArr 245 | { 246 | NSMutableArray *randomarr = [NSMutableArray array]; 247 | 248 | NSMutableArray *arr = [NSMutableArray array]; 249 | for (int i = 0; i < 10; i++) { 250 | [arr addObject:[NSString stringWithFormat:@"%d",i]]; 251 | } 252 | NSMutableArray *customRandomArr = [self getRandomArrFrome:arr]; 253 | [customRandomArr insertObject:@"退格" atIndex:3]; 254 | [customRandomArr insertObject:@"清空" atIndex:7]; 255 | [customRandomArr insertObject:@"隐藏" atIndex:11]; 256 | [customRandomArr insertObject:@"ABC" atIndex:12]; 257 | [customRandomArr insertObject:@"." atIndex:14]; 258 | [customRandomArr insertObject:@"确定" atIndex:15]; 259 | 260 | XMLog(@"customRandomArr = %@" ,customRandomArr); 261 | 262 | for (int i = 0; i < 16; i ++) { 263 | [randomarr addObject:customRandomArr[i]]; 264 | } 265 | return randomarr; 266 | } 267 | //数组随机 268 | -(NSMutableArray*)getRandomArrFrome:(NSArray*)arr 269 | { 270 | NSMutableArray *newArr = [NSMutableArray new]; 271 | while (newArr.count != arr.count) { 272 | //生成随机数 273 | int x =arc4random() % arr.count; 274 | id obj = arr[x]; 275 | if (![newArr containsObject:obj]) { 276 | [newArr addObject:obj]; 277 | } 278 | } 279 | return newArr; 280 | } 281 | 282 | @end 283 | -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/NumStrongKeyBoard/XMNumStrongKeyBoard.h: -------------------------------------------------------------------------------- 1 | // 2 | // XMNumStrongKeyBoard.h 3 | // XC_SmallTool 4 | // 5 | // Created by 风吹裤衩 on 2018/7/11. 6 | // Copyright © 2018年 gao bin. All rights reserved. 7 | /* 8 | 数字加强键盘 9 | */ 10 | 11 | #import "XMBasekeyBoardView.h" 12 | 13 | @interface XMNumStrongKeyBoard : XMBasekeyBoardView 14 | 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/NumStrongKeyBoard/XMNumStrongKeyBoard.m: -------------------------------------------------------------------------------- 1 | // 2 | // XMNumStrongKeyBoard.m 3 | // XC_SmallTool 4 | // 5 | // Created by 风吹裤衩 on 2018/7/11. 6 | // Copyright © 2018年 gao bin. All rights reserved. 7 | // 8 | 9 | 10 | #import "XMNumStrongKeyBoard.h" 11 | 12 | @implementation XMNumStrongKeyBoard 13 | 14 | -(instancetype)initWithFrame:(CGRect)frame 15 | { 16 | if (self = [super initWithFrame:frame]) { 17 | [self setUI]; 18 | } 19 | return self; 20 | } 21 | 22 | -(void)setUI 23 | { 24 | [super setUI]; 25 | UIButton *butn ; 26 | NSArray *arr = @[@"100",@"500",@"1000",@"2000",@"5000"]; 27 | for (int i = 0; i < arr.count; i++) { 28 | butn = [self creatfixedBtn]; 29 | butn.tag = 200 + i ; 30 | [butn setTitle:arr[i] forState:UIControlStateNormal]; 31 | butn.layer.borderWidth = 0.25; 32 | butn.layer.borderColor = keyBoardBtnColor.CGColor; 33 | [self addSubview:butn]; 34 | } 35 | 36 | NSArray *arr1 = @[@"1",@"2",@"3",@"退格",@"4",@"5",@"6",@"清空",@"7",@"8",@"9",@"隐藏",@"0",@"00",@"000",@"确定"]; 37 | for (int i = 0; i < arr1.count; i++) { 38 | if (i == 3) { //退格 39 | butn = [self creatDeleteBtn]; 40 | }else if(i == 7){ //清空 41 | butn = [self creatClearBtn]; 42 | }else if(i == 11){ //隐藏 43 | butn = [self creatHiddenBtn]; 44 | }else if(i == 15){ // 确定 45 | butn = [self creatDetermineBtnBtn]; 46 | }else{ 47 | butn = [self creatNormalBtn]; //普通按钮 48 | } 49 | 50 | butn.tag = 205 + i ; 51 | [butn setTitle:arr1[i] forState:UIControlStateNormal]; 52 | butn.layer.borderWidth = 0.25; 53 | butn.layer.borderColor = keyBoardBtnColor.CGColor; 54 | [self addSubview:butn]; 55 | } 56 | } 57 | 58 | -(void)layoutSubviews 59 | { 60 | [super layoutSubviews]; 61 | 62 | CGFloat btnW = self.width / 5; 63 | 64 | for (UIView *view in self.subviews) { 65 | if (view.tag < 205) { 66 | CGFloat btnH = keyBoardHeight/ 5 + 0.22; 67 | view.width = btnW; 68 | view.height = btnH; 69 | view.x = 0 ; 70 | view.y = (view.tag - 200 ) * btnH ; 71 | } 72 | // 4 x 4 73 | if (view.tag >= 205) { 74 | CGFloat btnH = keyBoardHeight / XM_EmotionMaxRows; 75 | 76 | view.width = btnW; 77 | view.height = btnH; 78 | view.x = ((view.tag - 205 )%XM_EmotionMaxCols) * btnW + btnW ; 79 | view.y = ((view.tag - 205 )/XM_EmotionMaxCols) * btnH ; 80 | } 81 | } 82 | } 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/Tools/UIView+XMFrame.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Frame.h 3 | // zhutong 4 | // 5 | // Created by apple on 16/10/19. 6 | // Copyright © 2016年 com.xc.zhutong. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIView (XMFrame) 12 | 13 | 14 | /** 15 | * 起点x坐标 16 | */ 17 | @property (nonatomic, assign) CGFloat x; 18 | /** 19 | * 起点y坐标 20 | */ 21 | @property (nonatomic, assign) CGFloat y; 22 | /** 23 | * 中心点x坐标 24 | */ 25 | @property (nonatomic, assign) CGFloat centerX; 26 | /** 27 | * 中心点y坐标 28 | */ 29 | @property (nonatomic, assign) CGFloat centerY; 30 | /** 31 | * 宽度 32 | */ 33 | @property (nonatomic, assign) CGFloat width; 34 | /** 35 | * 高度 36 | */ 37 | @property (nonatomic, assign) CGFloat height; 38 | /** 39 | * 顶部 40 | */ 41 | @property (nonatomic, assign) CGFloat top; 42 | /** 43 | * 底部 44 | */ 45 | @property (nonatomic, assign) CGFloat bottom; 46 | /** 47 | * 左边 48 | */ 49 | @property (nonatomic, assign) CGFloat left; 50 | /** 51 | * 右边 52 | */ 53 | @property (nonatomic, assign) CGFloat right; 54 | /** 55 | * size 56 | */ 57 | @property (nonatomic, assign) CGSize size; 58 | /** 59 | * 起点坐标 60 | */ 61 | @property (nonatomic, assign) CGPoint origin; 62 | 63 | 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/Tools/UIView+XMFrame.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Frame.m 3 | // zhutong 4 | // 5 | // Created by apple on 16/10/19. 6 | // Copyright © 2016年 com.xc.zhutong. All rights reserved. 7 | // 8 | 9 | #import "UIView+XMFrame.h" 10 | 11 | @implementation UIView (XMFrame) 12 | 13 | 14 | 15 | - (void)setX:(CGFloat)x { 16 | CGRect frame = self.frame; 17 | frame.origin.x = x; 18 | self.frame = frame; 19 | } 20 | 21 | - (void)setY:(CGFloat)y { 22 | CGRect frame = self.frame; 23 | frame.origin.y = y; 24 | self.frame = frame; 25 | } 26 | 27 | - (CGFloat)x { 28 | return self.frame.origin.x; 29 | } 30 | 31 | - (CGFloat)y { 32 | return self.frame.origin.y; 33 | } 34 | 35 | - (void)setCenterX:(CGFloat)centerX { 36 | 37 | CGPoint center = self.center; 38 | center.x = centerX; 39 | self.center = center; 40 | 41 | } 42 | 43 | - (CGFloat)centerX { 44 | return self.center.x; 45 | } 46 | 47 | - (void)setCenterY:(CGFloat)centerY{ 48 | CGPoint center = self.center; 49 | 50 | center.y = centerY; 51 | 52 | self.center = center; 53 | } 54 | 55 | - (CGFloat)centerY { 56 | return self.center.y; 57 | } 58 | 59 | - (void)setWidth:(CGFloat)width { 60 | CGRect frame = self.frame; 61 | frame.size.width = width; 62 | self.frame = frame; 63 | } 64 | 65 | - (void)setHeight:(CGFloat)height { 66 | CGRect frame = self.frame; 67 | frame.size.height = height; 68 | self.frame = frame; 69 | } 70 | 71 | - (CGFloat)height { 72 | return self.frame.size.height; 73 | } 74 | 75 | - (CGFloat)width { 76 | return self.frame.size.width; 77 | } 78 | 79 | - (void)setSize:(CGSize)size { 80 | CGRect frame = self.frame; 81 | frame.size = size; 82 | self.frame = frame; 83 | } 84 | 85 | - (CGSize)size { 86 | return self.frame.size; 87 | } 88 | 89 | - (void)setOrigin:(CGPoint)origin { 90 | CGRect frame = self.frame; 91 | frame.origin = origin; 92 | self.frame = frame; 93 | } 94 | 95 | - (CGPoint)origin { 96 | return self.frame.origin; 97 | } 98 | - (CGFloat)top 99 | { 100 | return self.frame.origin.y; 101 | } 102 | 103 | - (void)setTop:(CGFloat)top 104 | { 105 | CGRect frame = self.frame; 106 | frame.origin.y = top; 107 | self.frame = frame; 108 | } 109 | 110 | - (CGFloat)left 111 | { 112 | return self.frame.origin.x; 113 | } 114 | 115 | - (void)setLeft:(CGFloat)left 116 | { 117 | CGRect frame = self.frame; 118 | frame.origin.x = left; 119 | self.frame = frame; 120 | } 121 | 122 | 123 | - (CGFloat)bottom 124 | { 125 | return self.frame.size.height + self.frame.origin.y; 126 | } 127 | 128 | - (void)setBottom:(CGFloat)bottom 129 | { 130 | CGRect frame = self.frame; 131 | frame.origin.y = bottom - frame.size.height; 132 | self.frame = frame; 133 | } 134 | 135 | - (CGFloat)right 136 | { 137 | return self.frame.size.width + self.frame.origin.x; 138 | } 139 | 140 | - (void)setRight:(CGFloat)right 141 | { 142 | CGRect frame = self.frame; 143 | frame.origin.x = right - frame.size.width; 144 | self.frame = frame; 145 | } 146 | 147 | 148 | 149 | 150 | 151 | @end 152 | -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/WordKeyBoard/XMWordKeyBoardView.h: -------------------------------------------------------------------------------- 1 | // 2 | // KeyBoardView.h 3 | // KeyBoard 4 | // 5 | // Created by 风吹裤衩 on 2018/6/29. 6 | // Copyright © 2018年 风吹裤衩. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "XMBasekeyBoardView.h" 11 | 12 | /** 13 | word 键盘 14 | */ 15 | @interface XMWordKeyBoardView : XMBasekeyBoardView 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/WordKeyBoard/XMWordKeyBoardView.m: -------------------------------------------------------------------------------- 1 | // 2 | // KeyBoardView.m 3 | // KeyBoard 4 | // 5 | // Created by 风吹裤衩 on 2018/6/29. 6 | // Copyright © 2018年 风吹裤衩. All rights reserved. 7 | // 8 | 9 | #import "XMWordKeyBoardView.h" 10 | 11 | 12 | @interface XMWordKeyBoardView() 13 | { 14 | 15 | CGFloat topMargin ; //上面的距离 16 | CGFloat bottomMargin ; //下面的距离 17 | CGFloat leftMargin ; //最左边的距离 18 | CGFloat colMargin ;//行间距 19 | CGFloat rowMargin ;//列间距 20 | CGFloat topBtnW ; //按钮的宽度 21 | CGFloat topBtnH ; //按钮的高度 22 | } 23 | /** 装载切割好了的字符串 */ 24 | @property (nonatomic,strong)NSMutableArray *dataSource; 25 | 26 | /** 大小写切换按钮 */ 27 | @property (nonatomic,strong)CapsLockBtn *capsLockBtn; 28 | 29 | /** 退格按钮 */ 30 | @property (nonatomic,strong)DeleteBtn *deleteBtn; 31 | 32 | /** 隐藏按钮 */ 33 | @property (nonatomic,strong)HiddenBtn *hiddenBtn; 34 | 35 | /** 确定按钮 */ 36 | @property (nonatomic,strong)DetermineBtn *determinBtn; 37 | 38 | /** 空格按钮 */ 39 | @property (nonatomic,strong)SpaceBtn *spaceBtn; 40 | 41 | /** 字母和数字的切换按钮 */ 42 | @property (nonatomic,strong)SwitchBtn *switchBtn; 43 | 44 | /** 切换到字符按钮 */ 45 | @property (nonatomic,strong)SwitchBtn *switchCharBtn; 46 | 47 | /** 装26个小写的字母 */ 48 | @property (nonatomic,copy)NSMutableArray *lowercaseDataSorce ; 49 | 50 | /** 装26个大写的字母 */ 51 | @property (nonatomic,copy)NSMutableArray *aCapitalDataSorce ; 52 | 53 | @end 54 | 55 | @implementation XMWordKeyBoardView 56 | 57 | -(instancetype)init 58 | { 59 | if (self = [super init]) { 60 | [self setUI]; 61 | } 62 | return self; 63 | } 64 | 65 | -(instancetype)initWithFrame:(CGRect)frame 66 | { 67 | if (self = [super initWithFrame:frame]) { 68 | [self setUI]; 69 | } 70 | return self; 71 | } 72 | 73 | -(void)setUI 74 | { 75 | [super setUI]; 76 | 77 | topMargin = 10; //上面的距离 78 | bottomMargin = 10; //下面的距离 79 | leftMargin = 8; //最左边的距离 80 | colMargin = 2;//行间距 81 | rowMargin = 10;//列间距 82 | 83 | topBtnW = (Kwidth - 2 * leftMargin - 9 * colMargin) / 10; //按钮的宽度 84 | topBtnH = (keyBoardHeight - 5 * topMargin) * 0.25 ; //按钮的高度 85 | 86 | if (self.dataSource.count > 0) return ; 87 | NSString *string = @"qwertyuiopasdfghjklzxcvbnm"; 88 | for (int i = 0; i < string.length; i++) { 89 | NSString *str = [string substringWithRange:NSMakeRange(i, 1)]; 90 | [self.dataSource addObject:str]; 91 | UIButton *btn = [self creatNormalBtn]; 92 | [btn setTitle:str forState:UIControlStateNormal]; 93 | [btn setBackgroundImage :[self nomImage:YES] forState:UIControlStateNormal]; 94 | [btn setBackgroundImage :[self nomImage:NO] forState:UIControlStateHighlighted]; 95 | btn.tag = i + 1000 ; 96 | [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 97 | btn.backgroundColor = [UIColor clearColor]; 98 | [self addSubview:btn]; 99 | } 100 | self.delegate = self; 101 | [self addSubview:self.capsLockBtn]; 102 | [self addSubview:self.deleteBtn]; 103 | [self addSubview:self.switchBtn]; 104 | [self addSubview:self.hiddenBtn]; 105 | [self addSubview:self.spaceBtn]; 106 | [self addSubview:self.determinBtn]; 107 | [self addSubview:self.switchCharBtn]; 108 | [self.capsLockBtn addTarget:self action:@selector(capslockExchange:) forControlEvents:UIControlEventTouchUpInside]; 109 | } 110 | 111 | #pragma mark 布局 112 | /** 布局 */ 113 | -(void)layoutSubviews 114 | { 115 | [super layoutSubviews]; 116 | [self wordlayout];//字母的布局 117 | [self specialBtnLayout];//特殊按钮的布局 删除,空格,退格,大小写切换等 118 | 119 | } 120 | 121 | /** 特殊按钮的布局 */ 122 | -(void)specialBtnLayout 123 | { 124 | //大小写切换按钮位置 125 | self.capsLockBtn.x = leftMargin ; 126 | self.capsLockBtn.width = topBtnW * 1.5; 127 | self.capsLockBtn.height = topBtnH; 128 | self.capsLockBtn.y = topMargin + 2 * (topBtnH + rowMargin); 129 | 130 | UIView *zBtn = [self viewWithTag:1000 + 25]; 131 | //退格按钮位置 132 | self.deleteBtn.x = CGRectGetMaxX(zBtn.frame) + colMargin; 133 | self.deleteBtn.width = topBtnW * 1.5; 134 | self.deleteBtn.height = topBtnH; 135 | self.deleteBtn.y = topMargin + 2 * (topBtnH + rowMargin); 136 | 137 | //切换数字和字母键盘 123 138 | self.switchBtn.x = leftMargin ; 139 | self.switchBtn.y = topMargin + 3 * (topBtnH + rowMargin); 140 | self.switchBtn.width = topBtnW * 1.5; 141 | self.switchBtn.height = topBtnH; 142 | 143 | //隐藏按钮布局 144 | self.switchCharBtn.x = CGRectGetMaxX(self.switchBtn.frame) + colMargin; 145 | self.switchCharBtn.y = topMargin + 3 * (topBtnH + rowMargin); 146 | self.switchCharBtn.width = topBtnW * 1.5; 147 | self.switchCharBtn.height = topBtnH; 148 | 149 | //空格按钮布局 150 | self.spaceBtn.x = CGRectGetMaxX(self.switchCharBtn.frame) + colMargin; 151 | self.spaceBtn.y = topMargin + 3 * (topBtnH + rowMargin); 152 | self.spaceBtn.width = 3 * topBtnW + 4 * colMargin; 153 | self.spaceBtn.height = topBtnH; 154 | 155 | //字符按钮 156 | self.hiddenBtn.x = colMargin + CGRectGetMaxX(self.spaceBtn.frame) ; 157 | self.hiddenBtn.y = topMargin + 3 * (topBtnH + rowMargin); 158 | self.hiddenBtn.width = topBtnW * 1.5; 159 | self.hiddenBtn.height = topBtnH; 160 | 161 | // self.hiddenBtn.x = CGRectGetMaxX(self.switchBtn.frame) + colMargin; 162 | // self.hiddenBtn.y = topMargin + 3 * (topBtnH + rowMargin); 163 | // self.hiddenBtn.width = topBtnW * 1.5; 164 | // self.hiddenBtn.height = topBtnH; 165 | 166 | //确定按钮 167 | self.determinBtn.x = CGRectGetMaxX(self.hiddenBtn.frame) + colMargin; 168 | self.determinBtn.y = topMargin + 3 * (topBtnH + rowMargin); 169 | self.determinBtn.width = CGRectGetMaxX(self.deleteBtn.frame) - CGRectGetMaxX(self.hiddenBtn.frame) + colMargin; 170 | self.determinBtn.height = topBtnH; 171 | } 172 | 173 | /** 字母的布局 */ 174 | -(void)wordlayout 175 | { 176 | int i = 0 ; 177 | for (UIView *btn in self.subviews) { 178 | CGFloat col = i % 10; 179 | if (i < 10){ 180 | //字母键盘第一排 10 个 181 | btn.x = leftMargin + col * (topBtnW + colMargin); 182 | btn.y = topMargin + 0 * (topBtnH + rowMargin); 183 | 184 | }else if (10 <= i && i < 19 ) { 185 | //字母键盘第二排排 9 个 186 | btn.x = leftMargin + topBtnW * 0.5 + col * (topBtnW + colMargin); 187 | btn.y = topMargin + 1 * (topBtnH + rowMargin); 188 | 189 | }else if(i > 18){ 190 | //字母第三排 191 | if (i == 19) { 192 | btn.x = 1.5 * topBtnW + leftMargin + colMargin; 193 | }else{ 194 | btn.x = leftMargin + topBtnW * 2.5 + colMargin *2 + col * (topBtnW + colMargin); 195 | } 196 | btn.y = topMargin + 2 * (topBtnH + rowMargin); 197 | } 198 | btn.width = topBtnW; 199 | btn.height = topBtnH; 200 | i++; 201 | } 202 | } 203 | 204 | ///** 大小写切换事件处理 */ 205 | -(void)capslockExchange:(CapsLockBtn *)btn 206 | { 207 | btn.selected =! btn.selected; 208 | if (self.capsLockBtn.selected) { //小写切大写 209 | [self reloadword:NO]; 210 | }else{ 211 | [self reloadword:YES]; //大写切小写 212 | } 213 | } 214 | 215 | /** 刷新大小写 */ 216 | -(void)reloadword:(BOOL)isLowercase 217 | { 218 | if (isLowercase) { //大写切换成小写 219 | for (int i = 0; i<26; i++) { 220 | UIButton *wordBtn = [self viewWithTag:1000 + i]; 221 | [wordBtn setTitle:self.lowercaseDataSorce[i] forState:UIControlStateNormal]; 222 | } 223 | }else{ 224 | //小写切换成大写 225 | for (int i = 0; i<26; i++) { 226 | UIButton *wordBtn = [self viewWithTag:1000 + i]; 227 | [wordBtn setTitle:self.aCapitalDataSorce[i] forState:UIControlStateNormal]; 228 | } 229 | } 230 | } 231 | 232 | #pragma makr 内部方法 233 | /** 图片的拉伸 */ 234 | - (UIImage *)nomImage:(BOOL)isNom { 235 | 236 | /////获取bundle 里面的图片 237 | NSBundle *currenBundle = [NSBundle bundleForClass:[self class]]; 238 | if (isNom) { 239 | NSString *imagePath = [currenBundle pathForResource:@"c_chaKeyboardButton@2x.png" ofType:nil inDirectory:@"KeyBoardSource.Bundle"]; 240 | // 普通图片 241 | UIImage *image = [UIImage imageWithContentsOfFile:imagePath]; 242 | //部分拉升图片 243 | image = [image stretchableImageWithLeftCapWidth:image.size.width * 0.5 topCapHeight:image.size.height * 0.5]; 244 | return image; 245 | }else{ 246 | // 高亮图片 247 | NSString *imagePath = [currenBundle pathForResource:@"c_chaKeyboardButtonSel@2x.png" ofType:nil inDirectory:@"KeyBoardSource.Bundle"]; 248 | UIImage *highImage = [UIImage imageWithContentsOfFile:imagePath]; 249 | //部分拉升图片 250 | highImage = [highImage stretchableImageWithLeftCapWidth:highImage.size.width * 0.5 topCapHeight:highImage.size.height * 0.5]; 251 | return highImage; 252 | } 253 | } 254 | 255 | #pragma mark Lazy -----懒加载-------- 256 | -(CapsLockBtn *)capsLockBtn 257 | { 258 | if (!_capsLockBtn) { 259 | _capsLockBtn = [self creatCapsLockBtn]; 260 | _capsLockBtn.backgroundColor = [UIColor clearColor]; 261 | [_capsLockBtn setBackgroundImage:[self nomImage:NO] forState:UIControlStateNormal]; 262 | NSBundle *currenBundle = [NSBundle bundleForClass:[self class]]; 263 | NSString *shiftImagePath = [currenBundle pathForResource:@"c_chaKeyboardShiftButton@2x.png" ofType:nil inDirectory:@"KeyBoardSource.Bundle"]; 264 | 265 | NSString *xMshiftImagePath = [currenBundle pathForResource:@"CXXshift@2x.png" ofType:nil inDirectory:@"KeyBoardSource.Bundle"]; 266 | // 普通图片 267 | UIImage *image = [UIImage imageWithContentsOfFile:shiftImagePath]; 268 | UIImage *xmImage = [UIImage imageWithContentsOfFile:xMshiftImagePath]; 269 | 270 | [_capsLockBtn setBackgroundImage:image forState:UIControlStateHighlighted]; 271 | [_capsLockBtn setImage:image forState:UIControlStateNormal]; 272 | [_capsLockBtn setImage:xmImage forState:UIControlStateSelected]; 273 | 274 | _capsLockBtn.contentMode = UIViewContentModeCenter; 275 | } 276 | return _capsLockBtn; 277 | } 278 | -(DeleteBtn *)deleteBtn 279 | { 280 | if (!_deleteBtn) { 281 | _deleteBtn = [self creatDeleteBtn]; 282 | _deleteBtn.backgroundColor = [UIColor clearColor]; 283 | 284 | [_deleteBtn setBackgroundImage:[self nomImage:NO] forState:UIControlStateNormal]; 285 | [_deleteBtn setBackgroundImage:[self nomImage:YES] forState:UIControlStateHighlighted]; 286 | 287 | NSBundle *currenBundle = [NSBundle bundleForClass:[self class]]; 288 | NSString *deleteImagePath = [currenBundle pathForResource:@"c_character_keyboardDeleteButton@2x.png" ofType:nil inDirectory:@"KeyBoardSource.Bundle"]; 289 | NSString *deleteSelectmagePath = [currenBundle pathForResource:@"c_character_keyboardDeleteButtonSel@2x.png" ofType:nil inDirectory:@"KeyBoardSource.Bundle"]; 290 | 291 | UIImage *deleteImage = [UIImage imageWithContentsOfFile:deleteImagePath]; 292 | UIImage *deleteSelectxmImage = [UIImage imageWithContentsOfFile:deleteSelectmagePath]; 293 | 294 | [_deleteBtn setImage:deleteImage forState:UIControlStateNormal]; 295 | [_deleteBtn setImage:deleteSelectxmImage forState:UIControlStateHighlighted]; 296 | 297 | _deleteBtn.contentMode = UIViewContentModeCenter; 298 | } 299 | return _deleteBtn; 300 | } 301 | 302 | -(HiddenBtn *)hiddenBtn 303 | { 304 | if (!_hiddenBtn) { 305 | _hiddenBtn = [self creatHiddenBtn]; 306 | _hiddenBtn.backgroundColor = [UIColor clearColor]; 307 | [_hiddenBtn setBackgroundImage:[self nomImage:NO] forState:UIControlStateNormal]; 308 | [_hiddenBtn setBackgroundImage:[self nomImage:YES] forState:UIControlStateHighlighted]; 309 | _hiddenBtn.contentMode = UIViewContentModeCenter; 310 | [_hiddenBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 311 | [_hiddenBtn setTitle:@"隐藏" forState:UIControlStateNormal]; 312 | } 313 | return _hiddenBtn; 314 | } 315 | 316 | -(SpaceBtn *)spaceBtn 317 | { 318 | if (!_spaceBtn) { 319 | _spaceBtn = [self creatSpaceBtn]; 320 | _spaceBtn.backgroundColor = [UIColor clearColor]; 321 | 322 | [_spaceBtn setBackgroundImage:[self nomImage:NO] forState:UIControlStateNormal]; 323 | [_spaceBtn setBackgroundImage:[self nomImage:YES] forState:UIControlStateHighlighted]; 324 | [_spaceBtn setTitle:@"空格" forState:UIControlStateNormal]; 325 | [_spaceBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 326 | _spaceBtn.contentMode = UIViewContentModeCenter; 327 | } 328 | return _spaceBtn; 329 | } 330 | 331 | -(SwitchBtn *)switchBtn 332 | { 333 | if (!_switchBtn) { 334 | _switchBtn = [self creatSwitchBtn]; 335 | _switchBtn.backgroundColor = [UIColor clearColor]; 336 | 337 | [_switchBtn setBackgroundImage:[self nomImage:NO] forState:UIControlStateNormal]; 338 | [_switchBtn setBackgroundImage:[self nomImage:YES] forState:UIControlStateHighlighted]; 339 | [_switchBtn setTitle:@"123" forState:UIControlStateNormal]; 340 | [_switchBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 341 | _switchBtn.contentMode = UIViewContentModeCenter; 342 | } 343 | return _switchBtn; 344 | } 345 | 346 | -(SwitchBtn *)switchCharBtn 347 | { 348 | if (!_switchCharBtn) { 349 | _switchCharBtn = [self creatSwitchBtn]; 350 | _switchCharBtn.backgroundColor = [UIColor clearColor]; 351 | 352 | [_switchCharBtn setBackgroundImage:[self nomImage:NO] forState:UIControlStateNormal]; 353 | [_switchCharBtn setBackgroundImage:[self nomImage:YES] forState:UIControlStateHighlighted]; 354 | [_switchCharBtn setTitle:@"字符" forState:UIControlStateNormal]; 355 | [_switchCharBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 356 | _switchCharBtn.contentMode = UIViewContentModeCenter; 357 | } 358 | return _switchCharBtn; 359 | } 360 | 361 | -(DetermineBtn *)determinBtn 362 | { 363 | if (!_determinBtn) { 364 | _determinBtn = [self creatDetermineBtnBtn]; 365 | _determinBtn.backgroundColor = [UIColor clearColor]; 366 | 367 | [_determinBtn setBackgroundImage:[self nomImage:NO] forState:UIControlStateNormal]; 368 | [_determinBtn setBackgroundImage:[self nomImage:YES] forState:UIControlStateHighlighted]; 369 | [_determinBtn setTitle:@"确定" forState:UIControlStateNormal]; 370 | [_determinBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 371 | _determinBtn.contentMode = UIViewContentModeCenter; 372 | } 373 | return _determinBtn; 374 | } 375 | 376 | -(NSMutableArray *)lowercaseDataSorce 377 | { 378 | if (!_lowercaseDataSorce) { 379 | _lowercaseDataSorce = [NSMutableArray array]; 380 | NSString *string = @"qwertyuiopasdfghjklzxcvbnm"; 381 | for (int i = 0; i < string.length; i++) { 382 | NSString *str = [string substringWithRange:NSMakeRange(i, 1)]; 383 | [_lowercaseDataSorce addObject:str]; 384 | } 385 | } 386 | return _lowercaseDataSorce; 387 | } 388 | 389 | -(NSMutableArray *)aCapitalDataSorce 390 | { 391 | if (!_aCapitalDataSorce) { 392 | _aCapitalDataSorce = [NSMutableArray array]; 393 | NSString *string = @"QWERTYUIOPASDFGHJKLZXCVBNM"; 394 | for (int i = 0; i < string.length; i++) { 395 | NSString *str = [string substringWithRange:NSMakeRange(i, 1)]; 396 | [_aCapitalDataSorce addObject:str]; 397 | } 398 | } 399 | return _aCapitalDataSorce; 400 | } 401 | 402 | -(NSMutableArray *)dataSource 403 | { 404 | if (!_dataSource) { 405 | _dataSource = [NSMutableArray array]; 406 | } 407 | return _dataSource; 408 | } 409 | 410 | @end 411 | 412 | -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/XMKeyBoardHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // XMKeyBoardHeader.h 3 | // chexiaoxi 4 | // 5 | // Created by 风吹裤衩 on 2018/6/29. 6 | // Copyright © 2018年 风吹裤衩. All rights reserved. 7 | /* 8 | 键盘的内部配置 9 | */ 10 | 11 | #ifndef XMKeyBoardHeader_h 12 | #define XMKeyBoardHeader_h 13 | 14 | typedef void(^XMEmptyBlock)(void); 15 | typedef void(^XMCallBackBlock)(id userInfo); 16 | 17 | #import "UIView+XMFrame.h" 18 | 19 | typedef NS_ENUM(NSInteger,XMkeyBoardType) { 20 | XMkeyBoardType_Default = 0 , //系统自带键盘 21 | XMkeyBoardType_Word , //字母键盘 22 | XMkeyBoardType_charAndNumber , //字符数字键盘 23 | XMkeyBoardType_Number, //数字键盘 24 | XMkeyBoardType_OnlyNumber, //纯数字键盘 25 | XMkeyBoardType_RandomNumber, // 随机数字键盘 26 | XMkeyBoardType_StrongNumber,// 数字加强键盘 27 | XMkeyBoardType_NumberStyleOne, //数字键盘风格1 28 | XMkeyBoardType_IDCardNumber,// 身份证键盘 29 | XMkeyBoardType_CarNumHeader,// 汽车车牌头部键盘 川 粤 云 贵 。。。。 30 | XMkeyBoardType_CarContentNumber,///车牌数字键盘 31 | XMkeyBoardType_Emotion,// emoji 键盘 32 | }; 33 | 34 | #define Kwidth [UIScreen mainScreen].bounds.size.width 35 | #define Kheight [UIScreen mainScreen].bounds.size.height 36 | 37 | //数组键盘 一页中最多4行 38 | #define XM_EmotionMaxRows 4 39 | //数组键盘 一行中最多7列 40 | #define XM_EmotionMaxCols 4 41 | // 键盘的默认高度 42 | #define keyBoardHeight 219 43 | // 键盘的默认颜色 44 | #define keyBoardBackviewcolor [UIColor colorWithRed:209/255.0f green:213/255.0f blue:219/255.0f alpha:1] 45 | #define iPhoneX (Kwidth == 375.0f) && (Kheight == 812.0f) 46 | #define kBottomSafeHeight ((iPhoneX)?(34):(0)) //距离底部的安全距离 47 | 48 | 49 | // 默认键盘按钮颜色 50 | #define keyBoardBtnColor Color(224, 224, 244, 1) 51 | 52 | #define Color(r,g,b,a) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:a] 53 | 54 | 55 | 56 | /** 自定义打印打印 */ 57 | #ifdef DEBUG 58 | #define XMLog(format, ...) printf("\n[%s] %s [第%d行] %s\n", __TIME__, __FUNCTION__, __LINE__, [[NSString stringWithFormat:format, ## __VA_ARGS__] UTF8String]); 59 | #else 60 | #define XMLog(format, ...) 61 | #endif 62 | 63 | 64 | #endif /* XMKeyBoardHeader_h */ 65 | -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/XMKeyBoardView.h: -------------------------------------------------------------------------------- 1 | // 2 | // XMKeyBoardView.h 3 | // chexiaoxi 4 | // 5 | // Created by 风吹裤衩 on 2018/6/30. 6 | // Copyright © 2018年 风吹裤衩. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "XMBasekeyBoardView.h" 11 | #import "XMNumberkeyBoard.h" // 数字键盘 随机键盘 身份证键盘 12 | #import "XMWordKeyBoardView.h" //字母键盘 13 | #import "XMNumStrongKeyBoard.h" //数字加强 14 | #import "XMNumberKeyBoardStyleOne.h" //数字键盘风格1 15 | #import "XMCharKeyBoardView.h" //字符键盘 16 | #import "XMCarNumHeaderKeyBoard.h" //车牌头键盘 17 | #import "CarContentKeyBoard.h"//车牌号码键盘 18 | #import "XMKeyBoardHeader.h" 19 | @interface XMKeyBoardView : XMBasekeyBoardView 20 | 21 | 22 | @property (nonatomic,assign)XMkeyBoardType XMKeyBoardType; ///键盘属性 23 | 24 | 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/XMKeyBoardView.m: -------------------------------------------------------------------------------- 1 | // 2 | // XMKeyBoardView.m 3 | // chexiaoxi 4 | // 5 | // Created by 风吹裤衩 on 2018/6/30. 6 | // Copyright © 2018年 风吹裤衩. All rights reserved. 7 | // 8 | 9 | #import "XMKeyBoardView.h" 10 | 11 | @interface XMKeyBoardView() 12 | 13 | @property (nonatomic,strong)XMNumberkeyBoard *numKeyBoard; /// 数字键盘 14 | @property (nonatomic,strong)XMNumberkeyBoard *randomNumKeyBoard; /// 数字随机键盘 15 | @property (nonatomic,strong)XMNumberkeyBoard *cardIDKeyBoard; /// 身份证键盘 16 | @property (nonatomic,strong)XMNumberkeyBoard *onlynumberKeyBoard; /// 纯数字键盘 17 | @property (nonatomic,strong)XMWordKeyBoardView *wordKeyBoard;/// 文字键盘 18 | @property (nonatomic,strong)XMNumStrongKeyBoard *strongNumKeyBoard; /// 数字加强键盘 19 | @property (nonatomic,strong)XMNumberKeyBoardStyleOne *numberKeyboardstyleone;///数字键盘风格1 20 | @property (nonatomic,strong)XMCharKeyBoardView *charKeyBoard ; ///< 字符键盘 21 | @property (nonatomic,strong)XMCarNumHeaderKeyBoard *carNumHeaderKeyBoard ; ///< 车牌头键盘 22 | @property (nonatomic,strong)CarContentKeyBoard *carContentNumKeyBoard ; ///< 车牌号码键盘 23 | @property (nonatomic,assign)XMkeyBoardType creatXMKeyBoardType; ///记录创建的时候是什么键盘 24 | @end 25 | 26 | @implementation XMKeyBoardView 27 | 28 | -(instancetype)init 29 | { 30 | if (self = [super init]) { 31 | [self setUI]; 32 | } 33 | return self; 34 | } 35 | 36 | -(instancetype)initWithFrame:(CGRect)frame 37 | { 38 | if (self = [super initWithFrame:frame]) { 39 | [self setUI]; 40 | } 41 | return self; 42 | } 43 | 44 | -(void)setUI 45 | { 46 | _creatXMKeyBoardType = 0 ; //默认创建时候是 系统默认的键盘 47 | } 48 | 49 | -(void)setXMKeyBoardType:(XMkeyBoardType)XMKeyBoardType 50 | { 51 | _XMKeyBoardType = XMKeyBoardType; 52 | 53 | if (_creatXMKeyBoardType == 0) { //确保记录创建时候的键盘。只设置一次。 54 | _creatXMKeyBoardType = XMKeyBoardType ; //记录创建时候的键盘 55 | } 56 | } 57 | 58 | -(void)layoutSubviews 59 | { 60 | [super layoutSubviews]; 61 | switch (self.XMKeyBoardType) { 62 | case XMkeyBoardType_Default: 63 | break; 64 | case XMkeyBoardType_Number: 65 | [self addSubview:self.numKeyBoard]; 66 | break; 67 | case XMkeyBoardType_Word: 68 | [self addSubview:self.wordKeyBoard]; 69 | break; 70 | case XMkeyBoardType_RandomNumber: 71 | [self addSubview:self.randomNumKeyBoard]; 72 | break; 73 | case XMkeyBoardType_StrongNumber: 74 | [self addSubview:self.strongNumKeyBoard]; 75 | break; 76 | case XMkeyBoardType_IDCardNumber: 77 | [self addSubview:self.cardIDKeyBoard]; 78 | break; 79 | case XMkeyBoardType_OnlyNumber: 80 | [self addSubview:self.onlynumberKeyBoard]; 81 | break; 82 | case XMkeyBoardType_NumberStyleOne: 83 | [self addSubview:self.numberKeyboardstyleone]; 84 | break; 85 | case XMkeyBoardType_charAndNumber: 86 | [self addSubview:self.charKeyBoard]; 87 | break; 88 | case XMkeyBoardType_CarNumHeader: 89 | [self addSubview:self.carNumHeaderKeyBoard]; 90 | break; 91 | case XMkeyBoardType_CarContentNumber: 92 | [self addSubview:self.carContentNumKeyBoard]; 93 | break; 94 | default: 95 | break; 96 | } 97 | } 98 | 99 | #pragma mark XMkeyBoardViewDelegate 100 | /** 点击了内容 */ 101 | -(UIButton *)xmClickConten:(UIButton *)contenBtn 102 | { 103 | if ([self.delegate respondsToSelector:@selector(xmClickConten:)]) { 104 | switch (self.XMKeyBoardType) { 105 | case XMkeyBoardType_CarNumHeader: 106 | [self exhcnageCarContent:nil]; ///切换输入车牌号码的键盘 107 | break; 108 | 109 | default: 110 | break; 111 | } 112 | [self.delegate xmClickConten:contenBtn]; 113 | } 114 | return contenBtn; 115 | } 116 | 117 | /** 点击了确定 */ 118 | -(UIButton *)xmClickdetermine:(DetermineBtn *)determineBtn 119 | { 120 | if ([self.delegate respondsToSelector:@selector(xmClickdetermine:)]) { 121 | [self.delegate xmClickdetermine:determineBtn]; 122 | } 123 | return determineBtn; 124 | } 125 | 126 | 127 | /** 点击了清空 */ 128 | -(UIButton *)xmClickClear:(ClearBtn *)clearBtn 129 | { 130 | if ([self.delegate respondsToSelector:@selector(xmClickClear:)]) { 131 | [self.delegate xmClickClear:(ClearBtn *)clearBtn]; 132 | } 133 | return clearBtn; 134 | } 135 | 136 | /** 点击了退格 */ 137 | -(UIButton *)xmClickDelete:(DeleteBtn *)deleteBtn 138 | { 139 | if ([self.delegate respondsToSelector:@selector(xmClickDelete:)]) { 140 | [self.delegate xmClickDelete:deleteBtn]; 141 | } 142 | return deleteBtn; 143 | } 144 | 145 | /** 隐藏键盘 */ 146 | -(UIButton *)xmClickHidden:(HiddenBtn *)hiddenBtn 147 | { 148 | if ([self.delegate respondsToSelector:@selector(xmClickHidden:)]) { 149 | [self.delegate xmClickHidden:hiddenBtn]; 150 | } 151 | return hiddenBtn; 152 | } 153 | 154 | /** 点击了空格 */ 155 | -(UIButton *)xmClickspace:(SpaceBtn *)spaceBtn 156 | { 157 | if ([self.delegate respondsToSelector:@selector(xmClickspace:)]) { 158 | [self.delegate xmClickspace:spaceBtn]; 159 | } 160 | return spaceBtn; 161 | } 162 | 163 | /** 点击了固定输入内容的按钮,点击此按钮会清空以前的输入数据,显示此按钮输入的数据 */ 164 | -(UIButton *)xmClickfixedBtn:(fixedBtn *)fixedBtn 165 | { 166 | if ([self.delegate respondsToSelector:@selector(xmClickfixedBtn:)]) { 167 | [self.delegate xmClickfixedBtn:fixedBtn]; 168 | } 169 | return fixedBtn; 170 | } 171 | 172 | /** 切换键盘 */ 173 | -(UIButton *)xmClickswitch:(SwitchBtn *)switchBtn 174 | { 175 | if ([switchBtn.titleLabel.text isEqualToString:@"ABC"]) { 176 | [self exchangePinyin:switchBtn]; 177 | }else if([switchBtn.titleLabel.text isEqualToString: @"123"]){ 178 | [self exchangeNumber:switchBtn]; 179 | }else if([switchBtn.titleLabel.text isEqualToString: @"拼音"]){ 180 | [self exchangePinyin:switchBtn]; 181 | }else if([switchBtn.titleLabel.text isEqualToString: @"字符"]){ 182 | [self exchangeChar:switchBtn]; 183 | }else if([switchBtn.titleLabel.text isEqualToString: @"<-"]){ 184 | [self exhcnageCarheader:switchBtn]; 185 | }else if([switchBtn.titleLabel.text isEqualToString: @"更多"]){ 186 | [self exhcnageCarContent:switchBtn]; 187 | } 188 | return switchBtn; 189 | } 190 | 191 | //** 切换字符键盘 */ 192 | -(void)exchangeChar:(SwitchBtn *)switchBtn 193 | { 194 | self.XMKeyBoardType = XMkeyBoardType_charAndNumber ; 195 | [self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; 196 | [self setNeedsLayout]; 197 | [self layoutIfNeeded]; 198 | } 199 | 200 | //** 切换拼音键盘 */ 201 | -(void)exchangePinyin:(SwitchBtn *)switchBtn 202 | { 203 | self.XMKeyBoardType = XMkeyBoardType_Word ; 204 | [self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; 205 | [self setNeedsLayout]; 206 | [self layoutIfNeeded]; 207 | } 208 | 209 | //** 切换数字键盘 */ 210 | -(void)exchangeNumber:(SwitchBtn *)switchBtn 211 | { 212 | if(_creatXMKeyBoardType == XMkeyBoardType_RandomNumber){//如果创建的时候是随机数字键盘 213 | self.XMKeyBoardType = XMkeyBoardType_RandomNumber; //切换随机数组键盘 214 | }else{ 215 | //切换为数字键盘 216 | self.XMKeyBoardType = XMkeyBoardType_Number; 217 | } 218 | [self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; 219 | [self setNeedsLayout]; 220 | [self layoutIfNeeded]; 221 | } 222 | 223 | //** 切换车牌省份键盘 */ 224 | -(void)exhcnageCarheader:(SwitchBtn *)switchBtn 225 | { 226 | self.XMKeyBoardType = XMkeyBoardType_CarNumHeader ; 227 | [self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; 228 | [self setNeedsLayout]; 229 | [self layoutIfNeeded]; 230 | } 231 | 232 | //** 切换车牌省份键盘 */ 233 | -(void)exhcnageCarContent:(SwitchBtn *)switchBtn 234 | { 235 | self.XMKeyBoardType = XMkeyBoardType_CarContentNumber ; 236 | [self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; 237 | [self setNeedsLayout]; 238 | [self layoutIfNeeded]; 239 | } 240 | 241 | #pragma mark Lazy 242 | 243 | /** 身份证键盘 */ 244 | -(XMNumberkeyBoard *)cardIDKeyBoard 245 | { 246 | if (!_cardIDKeyBoard) { 247 | _cardIDKeyBoard = [[XMNumberkeyBoard alloc] initWithIDCard:CGRectZero]; 248 | _cardIDKeyBoard.delegate = self; 249 | _cardIDKeyBoard.height = keyBoardHeight; 250 | _cardIDKeyBoard.width = self.width; 251 | _cardIDKeyBoard.x = 0 ; 252 | _cardIDKeyBoard.y = 0 ; 253 | } 254 | return _cardIDKeyBoard; 255 | } 256 | 257 | /** 数字键盘 */ 258 | -(XMNumberkeyBoard *)numKeyBoard 259 | { 260 | if (!_numKeyBoard) { 261 | _numKeyBoard = [[XMNumberkeyBoard alloc] init]; 262 | _numKeyBoard.delegate = self; 263 | _numKeyBoard.height = keyBoardHeight; 264 | _numKeyBoard.width = self.width; 265 | _numKeyBoard.x = 0 ; 266 | _numKeyBoard.y = 0 ; 267 | } 268 | return _numKeyBoard; 269 | } 270 | 271 | /** 随机键盘没有做成懒加载。确保每次键盘都要改变 */ 272 | -(XMNumberkeyBoard *)randomNumKeyBoard 273 | { 274 | _randomNumKeyBoard = [[XMNumberkeyBoard alloc] initWithFrameRandom:CGRectZero]; 275 | _randomNumKeyBoard.delegate = self; 276 | _randomNumKeyBoard.height = keyBoardHeight; 277 | _randomNumKeyBoard.width = self.width; 278 | _randomNumKeyBoard.x = 0 ; 279 | _randomNumKeyBoard.y = 0 ; 280 | 281 | return _randomNumKeyBoard; 282 | } 283 | 284 | /** 数字加强键盘 */ 285 | -(XMNumStrongKeyBoard *)strongNumKeyBoard 286 | { 287 | if (!_strongNumKeyBoard) { 288 | _strongNumKeyBoard = [[XMNumStrongKeyBoard alloc] init]; 289 | _strongNumKeyBoard.delegate = self; 290 | _strongNumKeyBoard.height = keyBoardHeight; 291 | _strongNumKeyBoard.width = self.width; 292 | _strongNumKeyBoard.x = 0 ; 293 | _strongNumKeyBoard.y = 0 ; 294 | } 295 | return _strongNumKeyBoard; 296 | } 297 | 298 | //** 车牌省份 键盘 */ 299 | -(XMCarNumHeaderKeyBoard *)carNumHeaderKeyBoard 300 | { 301 | if (!_carNumHeaderKeyBoard) { 302 | _carNumHeaderKeyBoard = [[XMCarNumHeaderKeyBoard alloc] initWithFrame:CGRectZero]; 303 | _carNumHeaderKeyBoard.delegate = self; 304 | _carNumHeaderKeyBoard.height = keyBoardHeight; 305 | _carNumHeaderKeyBoard.width = self.width; 306 | _carNumHeaderKeyBoard.x = 0 ; 307 | _carNumHeaderKeyBoard.y = 0 ; 308 | } 309 | return _carNumHeaderKeyBoard; 310 | } 311 | 312 | //** 车牌号码键盘 */ 313 | -(CarContentKeyBoard *)carContentNumKeyBoard 314 | { 315 | if (!_carContentNumKeyBoard) { 316 | _carContentNumKeyBoard = [[CarContentKeyBoard alloc] initWithFrame:CGRectZero]; 317 | _carContentNumKeyBoard.delegate = self; 318 | _carContentNumKeyBoard.width = self.width; 319 | _carContentNumKeyBoard.height = keyBoardHeight; 320 | _carContentNumKeyBoard.x = 0 ; 321 | _carContentNumKeyBoard.y = 0 ; 322 | } 323 | return _carContentNumKeyBoard; 324 | } 325 | 326 | //** 纯数字键盘 */ 327 | -(XMNumberkeyBoard *)onlynumberKeyBoard 328 | { 329 | if (!_onlynumberKeyBoard) { 330 | _onlynumberKeyBoard = [[XMNumberkeyBoard alloc] initWithOnlyKeyBoard:CGRectZero]; 331 | _onlynumberKeyBoard.delegate = self; 332 | _onlynumberKeyBoard.height = keyBoardHeight; 333 | _onlynumberKeyBoard.width = self.width; 334 | _onlynumberKeyBoard.x = 0 ; 335 | _onlynumberKeyBoard.y = 0 ; 336 | } 337 | return _onlynumberKeyBoard; 338 | } 339 | 340 | //** 纯数字键盘 */ 341 | -(XMNumberKeyBoardStyleOne *)numberKeyboardstyleone 342 | { 343 | if (!_numberKeyboardstyleone) { 344 | _numberKeyboardstyleone = [[XMNumberKeyBoardStyleOne alloc] initWithFrame:CGRectZero]; 345 | _numberKeyboardstyleone.delegate = self; 346 | _numberKeyboardstyleone.width = self.width; 347 | _numberKeyboardstyleone.height = keyBoardHeight; 348 | _numberKeyboardstyleone.x = 0 ; 349 | _numberKeyboardstyleone.y = 0 ; 350 | } 351 | return _numberKeyboardstyleone; 352 | } 353 | 354 | //** 字符键盘 */ 355 | -(XMCharKeyBoardView *)charKeyBoard 356 | { 357 | if (!_charKeyBoard) { 358 | _charKeyBoard = [[XMCharKeyBoardView alloc] initWithFrame:CGRectZero]; 359 | _charKeyBoard.delegate = self; 360 | _charKeyBoard.width = self.width; 361 | _charKeyBoard.height = keyBoardHeight; 362 | _charKeyBoard.x = 0 ; 363 | _charKeyBoard.y = 0 ; 364 | } 365 | return _charKeyBoard; 366 | } 367 | 368 | /** 字母键盘 */ 369 | -(XMWordKeyBoardView *)wordKeyBoard 370 | { 371 | if (!_wordKeyBoard) { 372 | _wordKeyBoard = [[XMWordKeyBoardView alloc] init]; 373 | _wordKeyBoard.delegate = self; 374 | _wordKeyBoard.height = keyBoardHeight ; 375 | _wordKeyBoard.width = self.width; 376 | } 377 | return _wordKeyBoard; 378 | } 379 | 380 | @end 381 | -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/XMTextField.h: -------------------------------------------------------------------------------- 1 | // 2 | // XMTextField.h 3 | // XMTXCustomKeyBoard 4 | // 5 | // Created by 风吹裤衩 on 2018/11/8. 6 | // Copyright © 2018年 风吹裤衩. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "XMKeyBoardHeader.h" 11 | @interface XMTextField : UITextField 12 | 13 | @property (nonatomic,assign)XMkeyBoardType xmKeyBoardType; ///键盘属性 (数字,字母,随机密码键盘 等) 14 | 15 | @property (nonatomic,assign)NSInteger maxInpuptLenth; ///限制键盘的输入长度 16 | 17 | @property (nonatomic,copy)XMCallBackBlock inputTextBlock; ///< 文字改变时候的回调 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Classes/CXXkeyBoard/XMTextField.m: -------------------------------------------------------------------------------- 1 | // 2 | // XMTextField.m 3 | // XMTXCustomKeyBoard 4 | // 5 | // Created by 风吹裤衩 on 2018/11/8. 6 | // Copyright © 2018年 风吹裤衩. All rights reserved. 7 | // 8 | 9 | #import "XMTextField.h" 10 | #import "XMKeyBoardView.h" 11 | @interface XMTextField() 12 | 13 | @property (nonatomic,strong)XMKeyBoardView *xmKeyBoardView; 14 | 15 | @end 16 | 17 | @implementation XMTextField 18 | 19 | -(instancetype)init 20 | { 21 | if (self = [super init]) { 22 | 23 | [self setUI]; 24 | } 25 | return self; 26 | } 27 | 28 | //** 支持xib */ 29 | -(instancetype)initWithCoder:(NSCoder *)aDecoder 30 | { 31 | if (self = [super initWithCoder:aDecoder]) { 32 | [self setUI]; 33 | } 34 | return self; 35 | } 36 | 37 | -(void)setUI 38 | { 39 | ///限制长度 40 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(exhcnaghe) name:UITextFieldTextDidChangeNotification object:nil]; 41 | } 42 | 43 | -(void)exhcnaghe 44 | { 45 | if (self.maxInpuptLenth) { 46 | if (self.text.length > self.maxInpuptLenth - 1){ 47 | self.text = [self.text substringToIndex: self.maxInpuptLenth]; 48 | } 49 | } 50 | 51 | if (self.inputTextBlock) { 52 | self.inputTextBlock(self); 53 | } 54 | } 55 | 56 | -(void)dealloc 57 | { 58 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 59 | } 60 | 61 | #pragma mark 键盘属性在这里设置 62 | -(void)layoutSubviews 63 | { 64 | [super layoutSubviews]; 65 | if (self.xmKeyBoardType != XMkeyBoardType_Default) { //当不是默认键盘的时候 66 | self.inputView = self.xmKeyBoardView; 67 | _xmKeyBoardView.XMKeyBoardType = self.xmKeyBoardType; 68 | } 69 | } 70 | 71 | -(XMKeyBoardView *)xmKeyBoardView 72 | { 73 | if (!_xmKeyBoardView) { 74 | _xmKeyBoardView = [[XMKeyBoardView alloc] init]; 75 | _xmKeyBoardView.height = keyBoardHeight + kBottomSafeHeight; 76 | _xmKeyBoardView.width = Kwidth; 77 | _xmKeyBoardView.delegate = self; 78 | _xmKeyBoardView.backgroundColor = keyBoardBackviewcolor; 79 | } 80 | return _xmKeyBoardView; 81 | } 82 | #pragma mark XMkeyBoardViewDelegate 83 | /** 点击了内容 */ 84 | -(UIButton *)xmClickConten:(UIButton *)contenBtn 85 | { 86 | if (contenBtn.titleLabel.text.length == 0) { 87 | return nil; 88 | } 89 | [self insertText:contenBtn.titleLabel.text]; 90 | return contenBtn; 91 | } 92 | 93 | /** 点击了确定 */ 94 | -(UIButton *)xmClickdetermine:(DetermineBtn *)determineBtn 95 | { 96 | [self resignFirstResponder]; 97 | return determineBtn; 98 | } 99 | 100 | /** 点击了清空 */ 101 | -(UIButton *)xmClickClear:(ClearBtn *)clearBtn 102 | { 103 | self.text = @""; 104 | 105 | if (self.inputTextBlock) { 106 | self.inputTextBlock(self); 107 | } 108 | 109 | return clearBtn; 110 | } 111 | 112 | /** 点击了退格 */ 113 | -(UIButton *)xmClickDelete:(DeleteBtn *)deleteBtn 114 | { 115 | [self deleteBackward]; 116 | return deleteBtn; 117 | } 118 | 119 | /** 隐藏键盘 */ 120 | -(UIButton *)xmClickHidden:(HiddenBtn *)hiddenBtn 121 | { 122 | [self endEditing:YES]; 123 | return hiddenBtn; 124 | } 125 | 126 | /** 点击了空格 */ 127 | -(UIButton *)xmClickspace:(SpaceBtn *)spaceBtn 128 | { 129 | [self insertText:@" "]; 130 | return spaceBtn; 131 | } 132 | 133 | /** 点击了固定内容的按钮。点击此按钮,输入此按钮显示内容,清空输入框 */ 134 | -(UIButton *)xmClickfixedBtn:(fixedBtn *)fixedBtn 135 | { 136 | self.text = @""; 137 | [self insertText:fixedBtn.titleLabel.text]; 138 | return fixedBtn; 139 | } 140 | 141 | 142 | @end 143 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CustomKeyBoard 一个简单的自定有键盘轮子 2 | [![](https://img.shields.io/badge/language-Objective--C-f48041.svg?style=flat)](https://www.apple.com/)  3 | [![](http://img.shields.io/cocoapods/p/LEETheme.svg?style=flat)](http://cocoapods.org/?q=LEETheme)  4 | 5 | ####做的一个键盘的简单小轮子 。欢迎 点 ✨ 👏🏻👏🏻👏🏻👏🏻👏🏻 6 | 7 | # 演示 8 | 9 | ![111.gif](https://upload-images.jianshu.io/upload_images/2018474-ad637ef920422cb0.gif?imageMogr2/auto-orient/strip) 10 | ![222.gif](https://upload-images.jianshu.io/upload_images/2018474-be76138faaef271e.gif?imageMogr2/auto-orient/strip) 11 | 12 | 13 | 安装 14 | ============== 15 | 16 | ### CocoaPods 17 | 18 | 1. 将 cocoapods 更新至最新版本. 19 | pod 'XMTXCustomKeyBoard', '~> 1.1.3' 20 | 4. 导入 ``。 21 | 22 | ### 手动安装 23 | 1. 下载demo。 24 | 2. 把 demo中的 Classes 文件下的 CXXkeyBoard 文件夹 整体导入工程即可 25 | 3. 导入 `XMTextField.h `。 26 | 27 | 28 | 29 | 用法 30 | ============== 31 | 32 | #### pod 导入 33 | pod 'XMTXCustomKeyBoard', '~> 1.1.3' 34 | 35 | 不使用pod导入 那么 下载demo。把 demo中的 Classes 文件下的 CXXkeyBoard 文件夹 整体导入工程即可 36 | 37 | 如果是pod 导入 到入 创建 XMTextField 输入框,设置对应的枚举即可 ,下面是pod导入的使用方法。 非pod导入可参考demo 38 | 39 | ``` 40 | 41 | #import 42 | 43 | @interface ViewController () 44 | @property (weak, nonatomic) IBOutlet XMTextField *xmtextFile; 45 | 46 | @end 47 | 48 | @implementation ViewController 49 | 50 | - (void)viewDidLoad { 51 | [super viewDidLoad]; 52 | self.xmtextFile.xmKeyBoardType = XMkeyBoardType_CarNumHeader; 53 | } 54 | 55 | ``` 56 | 57 | 如何自定义 58 | ============== 59 | 60 | 如何自定义 简单的键盘 。可参考demo 中的 NumKeyBoardStyleOne。 61 | 62 | 1. 首先继承 XMBasekeyBoardView ,按照demo ,实现对应的ui即可 63 | 2. 实现了UI需要在头文件 XMKeyBoardHeader 添加对应的枚举 64 | 3. 枚举实现了 导入对应的 键盘类 到 XMKeyBoardView 然后设置成对应的属性,在懒加载实现 65 | 4. 在 XMKeyBoardView 的 layoutSubviews 实现对应枚举即可 66 | 67 | -------------------------------------------------------------------------------- /XMTXCustomKeyBoard.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint XMTXCustomKeyBoard.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 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 12 | # 13 | # These will help people to find your library, and whilst it 14 | # can feel like a chore to fill in it's definitely to your advantage. The 15 | # summary should be tweet-length, and the description more in depth. 16 | # 17 | 18 | s.name = "XMTXCustomKeyBoard" 19 | s.version = "1.1.3" 20 | s.summary = "XMTXCustomKeyBoard" 21 | 22 | # This description is used to generate tags and improve search results. 23 | # * Think: What does it do? Why did you write it? What is the focus? 24 | # * Try to keep it short, snappy and to the point. 25 | # * Write the description between the DESC delimiters below. 26 | # * Finally, don't worry about the indent, CocoaPods strips it! 27 | s.description = "XMTXCustomKeyBoard 是 一个简单的自定义键盘,支持 身份证键盘。数字键盘,密码随机键盘,等部分键盘" 28 | 29 | s.homepage = "https://github.com/cgmsuccess/CustomKeyBoard" 30 | # s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif" 31 | 32 | 33 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 34 | # 35 | # Licensing your code is important. See http://choosealicense.com for more info. 36 | # CocoaPods will detect a license file if there is a named LICENSE* 37 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 38 | # 39 | 40 | s.license = "MIT" 41 | # s.license = { :type => "MIT", :file => "FILE_LICENSE" } 42 | 43 | 44 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 45 | # 46 | # Specify the authors of the library, with email addresses. Email addresses 47 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 48 | # accepts just a name if you'd rather not provide an email address. 49 | # 50 | # Specify a social_media_url where others can refer to, for example a twitter 51 | # profile URL. 52 | # 53 | 54 | s.author = { "风吹裤衩" => "cgmsuccess@163.com" } 55 | # Or just: s.author = "风吹裤衩" 56 | # s.authors = { "风吹裤衩" => "cgmsuccess@163.com" } 57 | # s.social_media_url = "http://twitter.com" 58 | 59 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 60 | # 61 | # If this Pod runs only on iOS or OS X, then specify the platform and 62 | # the deployment target. You can optionally include the target after the platform. 63 | # 64 | 65 | s.platform = :ios 66 | s.platform = :ios, "8.0" 67 | 68 | # When using multiple platforms 69 | # s.ios.deployment_target = "5.0" 70 | # s.osx.deployment_target = "10.7" 71 | # s.watchos.deployment_target = "2.0" 72 | # s.tvos.deployment_target = "9.0" 73 | 74 | 75 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 76 | # 77 | # Specify the location from where the source should be retrieved. 78 | # Supports git, hg, bzr, svn and HTTP. 79 | # 80 | 81 | s.source = { :git => "https://github.com/cgmsuccess/CustomKeyBoard.git", :tag => "#{s.version}" } 82 | 83 | 84 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 85 | # 86 | # CocoaPods is smart about how it includes source code. For source files 87 | # giving a folder will include any swift, h, m, mm, c & cpp files. 88 | # For header files it will include any header in the folder. 89 | # Not including the public_header_files will make all headers public. 90 | # 91 | 92 | s.source_files = "Classes","Classes/*", "Classes/**/*.{h,m}" 93 | # s.exclude_files = "Classes/Exclude" 94 | 95 | # s.public_header_files = "Classes/**/*.h" 96 | 97 | 98 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 99 | # 100 | # A list of resources included with the Pod. These are copied into the 101 | # target bundle with a build phase script. Anything else will be cleaned. 102 | # You can preserve files from being cleaned, please don't preserve 103 | # non-essential files like tests, examples and documentation. 104 | # 105 | 106 | s.resource = "Classes/**/KeyBoardSource.bundle" 107 | # s.resources = "Resources/*.png" 108 | 109 | # s.preserve_paths = "FilesToSave", "MoreFilesToSave" 110 | 111 | 112 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 113 | # 114 | # Link your library with frameworks, or libraries. Libraries do not include 115 | # the lib prefix of their name. 116 | # 117 | 118 | # s.framework = "SomeFramework" 119 | # s.frameworks = "SomeFramework", "AnotherFramework" 120 | 121 | # s.library = "iconv" 122 | # s.libraries = "iconv", "xml2" 123 | 124 | 125 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 126 | # 127 | # If your library depends on compiler flags you can set them in the xcconfig hash 128 | # where they will only apply to your library. If you depend on other Podspecs 129 | # you can include multiple dependencies to ensure it works. 130 | 131 | # s.requires_arc = true 132 | 133 | # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 134 | # s.dependency "JSONKit", "~> 1.4" 135 | 136 | end 137 | -------------------------------------------------------------------------------- /XMTXCustomKeyBoard/XMTXCustomKeyBoard.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 23480D45219D1B3E0027A03F /* CarContentKeyBoard.m in Sources */ = {isa = PBXBuildFile; fileRef = 23480D44219D1B3E0027A03F /* CarContentKeyBoard.m */; }; 11 | 23480D48219D56950027A03F /* UITextField+CHTHealper.m in Sources */ = {isa = PBXBuildFile; fileRef = 23480D47219D56950027A03F /* UITextField+CHTHealper.m */; }; 12 | 23554DC12199105700474124 /* XMCharKeyBoardView.m in Sources */ = {isa = PBXBuildFile; fileRef = 23554DC02199105700474124 /* XMCharKeyBoardView.m */; }; 13 | 23581669219435B300CF8A77 /* XMTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 23581668219435B300CF8A77 /* XMTextField.m */; }; 14 | 235A42F6219A75D400747141 /* XMCarNumHeaderKeyBoard.m in Sources */ = {isa = PBXBuildFile; fileRef = 235A42F5219A75D400747141 /* XMCarNumHeaderKeyBoard.m */; }; 15 | 237652E6219578AB00D8A021 /* KeyBoardSource.Bundle in Resources */ = {isa = PBXBuildFile; fileRef = 237652E5219578AB00D8A021 /* KeyBoardSource.Bundle */; }; 16 | F7A264A4218EFE9E00674D36 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F7A264A3218EFE9E00674D36 /* AppDelegate.m */; }; 17 | F7A264A7218EFE9E00674D36 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F7A264A6218EFE9E00674D36 /* ViewController.m */; }; 18 | F7A264AA218EFE9E00674D36 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7A264A8218EFE9E00674D36 /* Main.storyboard */; }; 19 | F7A264AC218EFE9E00674D36 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F7A264AB218EFE9E00674D36 /* Assets.xcassets */; }; 20 | F7A264AF218EFE9E00674D36 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7A264AD218EFE9E00674D36 /* LaunchScreen.storyboard */; }; 21 | F7A264B2218EFE9E00674D36 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F7A264B1218EFE9E00674D36 /* main.m */; }; 22 | F7A264BC218EFE9E00674D36 /* XMTXCustomKeyBoardTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F7A264BB218EFE9E00674D36 /* XMTXCustomKeyBoardTests.m */; }; 23 | F7A264C7218EFE9E00674D36 /* XMTXCustomKeyBoardUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = F7A264C6218EFE9E00674D36 /* XMTXCustomKeyBoardUITests.m */; }; 24 | F7A2654F218F0AFF00674D36 /* XMBasekeyBoardView.m in Sources */ = {isa = PBXBuildFile; fileRef = F7A26525218F0AFF00674D36 /* XMBasekeyBoardView.m */; }; 25 | F7A26550218F0AFF00674D36 /* UIView+XMFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = F7A26528218F0AFF00674D36 /* UIView+XMFrame.m */; }; 26 | F7A26551218F0AFF00674D36 /* XMNumberkeyBoard.m in Sources */ = {isa = PBXBuildFile; fileRef = F7A2652B218F0AFF00674D36 /* XMNumberkeyBoard.m */; }; 27 | F7A26552218F0AFF00674D36 /* XMWordKeyBoardView.m in Sources */ = {isa = PBXBuildFile; fileRef = F7A2652D218F0AFF00674D36 /* XMWordKeyBoardView.m */; }; 28 | F7A26553218F0AFF00674D36 /* XMNumStrongKeyBoard.m in Sources */ = {isa = PBXBuildFile; fileRef = F7A26530218F0AFF00674D36 /* XMNumStrongKeyBoard.m */; }; 29 | F7A26554218F0AFF00674D36 /* XMKeyBoardView.m in Sources */ = {isa = PBXBuildFile; fileRef = F7A26532218F0AFF00674D36 /* XMKeyBoardView.m */; }; 30 | F7D027E12197DFBC002D2CDF /* XMNumberKeyBoardStyleOne.m in Sources */ = {isa = PBXBuildFile; fileRef = F7D027E02197DFBC002D2CDF /* XMNumberKeyBoardStyleOne.m */; }; 31 | /* End PBXBuildFile section */ 32 | 33 | /* Begin PBXContainerItemProxy section */ 34 | F7A264B8218EFE9E00674D36 /* PBXContainerItemProxy */ = { 35 | isa = PBXContainerItemProxy; 36 | containerPortal = F7A26497218EFE9E00674D36 /* Project object */; 37 | proxyType = 1; 38 | remoteGlobalIDString = F7A2649E218EFE9E00674D36; 39 | remoteInfo = XMTXCustomKeyBoard; 40 | }; 41 | F7A264C3218EFE9E00674D36 /* PBXContainerItemProxy */ = { 42 | isa = PBXContainerItemProxy; 43 | containerPortal = F7A26497218EFE9E00674D36 /* Project object */; 44 | proxyType = 1; 45 | remoteGlobalIDString = F7A2649E218EFE9E00674D36; 46 | remoteInfo = XMTXCustomKeyBoard; 47 | }; 48 | /* End PBXContainerItemProxy section */ 49 | 50 | /* Begin PBXFileReference section */ 51 | 23480D43219D1B3E0027A03F /* CarContentKeyBoard.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CarContentKeyBoard.h; sourceTree = ""; }; 52 | 23480D44219D1B3E0027A03F /* CarContentKeyBoard.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CarContentKeyBoard.m; sourceTree = ""; }; 53 | 23480D46219D56950027A03F /* UITextField+CHTHealper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITextField+CHTHealper.h"; sourceTree = ""; }; 54 | 23480D47219D56950027A03F /* UITextField+CHTHealper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITextField+CHTHealper.m"; sourceTree = ""; }; 55 | 23554DBF2199105700474124 /* XMCharKeyBoardView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XMCharKeyBoardView.h; sourceTree = ""; }; 56 | 23554DC02199105700474124 /* XMCharKeyBoardView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XMCharKeyBoardView.m; sourceTree = ""; }; 57 | 23581667219435B300CF8A77 /* XMTextField.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XMTextField.h; sourceTree = ""; }; 58 | 23581668219435B300CF8A77 /* XMTextField.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XMTextField.m; sourceTree = ""; }; 59 | 235A42F4219A75D400747141 /* XMCarNumHeaderKeyBoard.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XMCarNumHeaderKeyBoard.h; sourceTree = ""; }; 60 | 235A42F5219A75D400747141 /* XMCarNumHeaderKeyBoard.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XMCarNumHeaderKeyBoard.m; sourceTree = ""; }; 61 | 237652E5219578AB00D8A021 /* KeyBoardSource.Bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = KeyBoardSource.Bundle; sourceTree = ""; }; 62 | F7A2649F218EFE9E00674D36 /* XMTXCustomKeyBoard.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = XMTXCustomKeyBoard.app; sourceTree = BUILT_PRODUCTS_DIR; }; 63 | F7A264A2218EFE9E00674D36 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 64 | F7A264A3218EFE9E00674D36 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 65 | F7A264A5218EFE9E00674D36 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 66 | F7A264A6218EFE9E00674D36 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 67 | F7A264A9218EFE9E00674D36 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 68 | F7A264AB218EFE9E00674D36 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 69 | F7A264AE218EFE9E00674D36 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 70 | F7A264B0218EFE9E00674D36 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 71 | F7A264B1218EFE9E00674D36 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 72 | F7A264B7218EFE9E00674D36 /* XMTXCustomKeyBoardTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XMTXCustomKeyBoardTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 73 | F7A264BB218EFE9E00674D36 /* XMTXCustomKeyBoardTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XMTXCustomKeyBoardTests.m; sourceTree = ""; }; 74 | F7A264BD218EFE9E00674D36 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 75 | F7A264C2218EFE9E00674D36 /* XMTXCustomKeyBoardUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XMTXCustomKeyBoardUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 76 | F7A264C6218EFE9E00674D36 /* XMTXCustomKeyBoardUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XMTXCustomKeyBoardUITests.m; sourceTree = ""; }; 77 | F7A264C8218EFE9E00674D36 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 78 | F7A26524218F0AFF00674D36 /* XMBasekeyBoardView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMBasekeyBoardView.h; sourceTree = ""; }; 79 | F7A26525218F0AFF00674D36 /* XMBasekeyBoardView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XMBasekeyBoardView.m; sourceTree = ""; }; 80 | F7A26527218F0AFF00674D36 /* UIView+XMFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+XMFrame.h"; sourceTree = ""; }; 81 | F7A26528218F0AFF00674D36 /* UIView+XMFrame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+XMFrame.m"; sourceTree = ""; }; 82 | F7A2652A218F0AFF00674D36 /* XMNumberkeyBoard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMNumberkeyBoard.h; sourceTree = ""; }; 83 | F7A2652B218F0AFF00674D36 /* XMNumberkeyBoard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XMNumberkeyBoard.m; sourceTree = ""; }; 84 | F7A2652D218F0AFF00674D36 /* XMWordKeyBoardView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XMWordKeyBoardView.m; sourceTree = ""; }; 85 | F7A2652E218F0AFF00674D36 /* XMWordKeyBoardView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMWordKeyBoardView.h; sourceTree = ""; }; 86 | F7A26530218F0AFF00674D36 /* XMNumStrongKeyBoard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XMNumStrongKeyBoard.m; sourceTree = ""; }; 87 | F7A26531218F0AFF00674D36 /* XMNumStrongKeyBoard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMNumStrongKeyBoard.h; sourceTree = ""; }; 88 | F7A26532218F0AFF00674D36 /* XMKeyBoardView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XMKeyBoardView.m; sourceTree = ""; }; 89 | F7A26533218F0AFF00674D36 /* XMKeyBoardHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMKeyBoardHeader.h; sourceTree = ""; }; 90 | F7A2654E218F0AFF00674D36 /* XMKeyBoardView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMKeyBoardView.h; sourceTree = ""; }; 91 | F7D027DF2197DFBC002D2CDF /* XMNumberKeyBoardStyleOne.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XMNumberKeyBoardStyleOne.h; sourceTree = ""; }; 92 | F7D027E02197DFBC002D2CDF /* XMNumberKeyBoardStyleOne.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XMNumberKeyBoardStyleOne.m; sourceTree = ""; }; 93 | /* End PBXFileReference section */ 94 | 95 | /* Begin PBXFrameworksBuildPhase section */ 96 | F7A2649C218EFE9E00674D36 /* Frameworks */ = { 97 | isa = PBXFrameworksBuildPhase; 98 | buildActionMask = 2147483647; 99 | files = ( 100 | ); 101 | runOnlyForDeploymentPostprocessing = 0; 102 | }; 103 | F7A264B4218EFE9E00674D36 /* Frameworks */ = { 104 | isa = PBXFrameworksBuildPhase; 105 | buildActionMask = 2147483647; 106 | files = ( 107 | ); 108 | runOnlyForDeploymentPostprocessing = 0; 109 | }; 110 | F7A264BF218EFE9E00674D36 /* Frameworks */ = { 111 | isa = PBXFrameworksBuildPhase; 112 | buildActionMask = 2147483647; 113 | files = ( 114 | ); 115 | runOnlyForDeploymentPostprocessing = 0; 116 | }; 117 | /* End PBXFrameworksBuildPhase section */ 118 | 119 | /* Begin PBXGroup section */ 120 | 23480D42219D1B170027A03F /* CarContentKeyBoard */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | 23480D43219D1B3E0027A03F /* CarContentKeyBoard.h */, 124 | 23480D44219D1B3E0027A03F /* CarContentKeyBoard.m */, 125 | ); 126 | path = CarContentKeyBoard; 127 | sourceTree = ""; 128 | }; 129 | 23554DBE2199101B00474124 /* CharKeyBoard */ = { 130 | isa = PBXGroup; 131 | children = ( 132 | 23554DBF2199105700474124 /* XMCharKeyBoardView.h */, 133 | 23554DC02199105700474124 /* XMCharKeyBoardView.m */, 134 | ); 135 | path = CharKeyBoard; 136 | sourceTree = ""; 137 | }; 138 | 235A42F3219A75A900747141 /* CarNumHeaderKeyBoard */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | 235A42F4219A75D400747141 /* XMCarNumHeaderKeyBoard.h */, 142 | 235A42F5219A75D400747141 /* XMCarNumHeaderKeyBoard.m */, 143 | ); 144 | path = CarNumHeaderKeyBoard; 145 | sourceTree = ""; 146 | }; 147 | F7A26496218EFE9E00674D36 = { 148 | isa = PBXGroup; 149 | children = ( 150 | F7A26521218F0AFF00674D36 /* Classes */, 151 | F7A264A1218EFE9E00674D36 /* XMTXCustomKeyBoard */, 152 | F7A264BA218EFE9E00674D36 /* XMTXCustomKeyBoardTests */, 153 | F7A264C5218EFE9E00674D36 /* XMTXCustomKeyBoardUITests */, 154 | F7A264A0218EFE9E00674D36 /* Products */, 155 | ); 156 | sourceTree = ""; 157 | }; 158 | F7A264A0218EFE9E00674D36 /* Products */ = { 159 | isa = PBXGroup; 160 | children = ( 161 | F7A2649F218EFE9E00674D36 /* XMTXCustomKeyBoard.app */, 162 | F7A264B7218EFE9E00674D36 /* XMTXCustomKeyBoardTests.xctest */, 163 | F7A264C2218EFE9E00674D36 /* XMTXCustomKeyBoardUITests.xctest */, 164 | ); 165 | name = Products; 166 | sourceTree = ""; 167 | }; 168 | F7A264A1218EFE9E00674D36 /* XMTXCustomKeyBoard */ = { 169 | isa = PBXGroup; 170 | children = ( 171 | F7A264A2218EFE9E00674D36 /* AppDelegate.h */, 172 | F7A264A3218EFE9E00674D36 /* AppDelegate.m */, 173 | F7A264A5218EFE9E00674D36 /* ViewController.h */, 174 | F7A264A6218EFE9E00674D36 /* ViewController.m */, 175 | 23480D46219D56950027A03F /* UITextField+CHTHealper.h */, 176 | 23480D47219D56950027A03F /* UITextField+CHTHealper.m */, 177 | F7A264A8218EFE9E00674D36 /* Main.storyboard */, 178 | F7A264AB218EFE9E00674D36 /* Assets.xcassets */, 179 | F7A264AD218EFE9E00674D36 /* LaunchScreen.storyboard */, 180 | F7A264B0218EFE9E00674D36 /* Info.plist */, 181 | F7A264B1218EFE9E00674D36 /* main.m */, 182 | ); 183 | path = XMTXCustomKeyBoard; 184 | sourceTree = ""; 185 | }; 186 | F7A264BA218EFE9E00674D36 /* XMTXCustomKeyBoardTests */ = { 187 | isa = PBXGroup; 188 | children = ( 189 | F7A264BB218EFE9E00674D36 /* XMTXCustomKeyBoardTests.m */, 190 | F7A264BD218EFE9E00674D36 /* Info.plist */, 191 | ); 192 | path = XMTXCustomKeyBoardTests; 193 | sourceTree = ""; 194 | }; 195 | F7A264C5218EFE9E00674D36 /* XMTXCustomKeyBoardUITests */ = { 196 | isa = PBXGroup; 197 | children = ( 198 | F7A264C6218EFE9E00674D36 /* XMTXCustomKeyBoardUITests.m */, 199 | F7A264C8218EFE9E00674D36 /* Info.plist */, 200 | ); 201 | path = XMTXCustomKeyBoardUITests; 202 | sourceTree = ""; 203 | }; 204 | F7A26521218F0AFF00674D36 /* Classes */ = { 205 | isa = PBXGroup; 206 | children = ( 207 | F7A26522218F0AFF00674D36 /* CXXkeyBoard */, 208 | ); 209 | name = Classes; 210 | path = ../Classes; 211 | sourceTree = ""; 212 | }; 213 | F7A26522218F0AFF00674D36 /* CXXkeyBoard */ = { 214 | isa = PBXGroup; 215 | children = ( 216 | 23480D42219D1B170027A03F /* CarContentKeyBoard */, 217 | 235A42F3219A75A900747141 /* CarNumHeaderKeyBoard */, 218 | 23554DBE2199101B00474124 /* CharKeyBoard */, 219 | F7D027DE2197DFA4002D2CDF /* NumKeyBoardStyleOne */, 220 | F7A26523218F0AFF00674D36 /* CXXBaseKeyBoard */, 221 | F7A26526218F0AFF00674D36 /* Tools */, 222 | F7A26529218F0AFF00674D36 /* NumKeyboard */, 223 | F7A2652C218F0AFF00674D36 /* WordKeyBoard */, 224 | F7A2652F218F0AFF00674D36 /* NumStrongKeyBoard */, 225 | F7A26533218F0AFF00674D36 /* XMKeyBoardHeader.h */, 226 | F7A2654E218F0AFF00674D36 /* XMKeyBoardView.h */, 227 | F7A26532218F0AFF00674D36 /* XMKeyBoardView.m */, 228 | 23581667219435B300CF8A77 /* XMTextField.h */, 229 | 23581668219435B300CF8A77 /* XMTextField.m */, 230 | 237652E5219578AB00D8A021 /* KeyBoardSource.Bundle */, 231 | ); 232 | path = CXXkeyBoard; 233 | sourceTree = ""; 234 | }; 235 | F7A26523218F0AFF00674D36 /* CXXBaseKeyBoard */ = { 236 | isa = PBXGroup; 237 | children = ( 238 | F7A26524218F0AFF00674D36 /* XMBasekeyBoardView.h */, 239 | F7A26525218F0AFF00674D36 /* XMBasekeyBoardView.m */, 240 | ); 241 | path = CXXBaseKeyBoard; 242 | sourceTree = ""; 243 | }; 244 | F7A26526218F0AFF00674D36 /* Tools */ = { 245 | isa = PBXGroup; 246 | children = ( 247 | F7A26527218F0AFF00674D36 /* UIView+XMFrame.h */, 248 | F7A26528218F0AFF00674D36 /* UIView+XMFrame.m */, 249 | ); 250 | path = Tools; 251 | sourceTree = ""; 252 | }; 253 | F7A26529218F0AFF00674D36 /* NumKeyboard */ = { 254 | isa = PBXGroup; 255 | children = ( 256 | F7A2652A218F0AFF00674D36 /* XMNumberkeyBoard.h */, 257 | F7A2652B218F0AFF00674D36 /* XMNumberkeyBoard.m */, 258 | ); 259 | path = NumKeyboard; 260 | sourceTree = ""; 261 | }; 262 | F7A2652C218F0AFF00674D36 /* WordKeyBoard */ = { 263 | isa = PBXGroup; 264 | children = ( 265 | F7A2652E218F0AFF00674D36 /* XMWordKeyBoardView.h */, 266 | F7A2652D218F0AFF00674D36 /* XMWordKeyBoardView.m */, 267 | ); 268 | path = WordKeyBoard; 269 | sourceTree = ""; 270 | }; 271 | F7A2652F218F0AFF00674D36 /* NumStrongKeyBoard */ = { 272 | isa = PBXGroup; 273 | children = ( 274 | F7A26530218F0AFF00674D36 /* XMNumStrongKeyBoard.m */, 275 | F7A26531218F0AFF00674D36 /* XMNumStrongKeyBoard.h */, 276 | ); 277 | path = NumStrongKeyBoard; 278 | sourceTree = ""; 279 | }; 280 | F7D027DE2197DFA4002D2CDF /* NumKeyBoardStyleOne */ = { 281 | isa = PBXGroup; 282 | children = ( 283 | F7D027DF2197DFBC002D2CDF /* XMNumberKeyBoardStyleOne.h */, 284 | F7D027E02197DFBC002D2CDF /* XMNumberKeyBoardStyleOne.m */, 285 | ); 286 | path = NumKeyBoardStyleOne; 287 | sourceTree = ""; 288 | }; 289 | /* End PBXGroup section */ 290 | 291 | /* Begin PBXNativeTarget section */ 292 | F7A2649E218EFE9E00674D36 /* XMTXCustomKeyBoard */ = { 293 | isa = PBXNativeTarget; 294 | buildConfigurationList = F7A264CB218EFE9E00674D36 /* Build configuration list for PBXNativeTarget "XMTXCustomKeyBoard" */; 295 | buildPhases = ( 296 | F7A2649B218EFE9E00674D36 /* Sources */, 297 | F7A2649C218EFE9E00674D36 /* Frameworks */, 298 | F7A2649D218EFE9E00674D36 /* Resources */, 299 | ); 300 | buildRules = ( 301 | ); 302 | dependencies = ( 303 | ); 304 | name = XMTXCustomKeyBoard; 305 | productName = XMTXCustomKeyBoard; 306 | productReference = F7A2649F218EFE9E00674D36 /* XMTXCustomKeyBoard.app */; 307 | productType = "com.apple.product-type.application"; 308 | }; 309 | F7A264B6218EFE9E00674D36 /* XMTXCustomKeyBoardTests */ = { 310 | isa = PBXNativeTarget; 311 | buildConfigurationList = F7A264CE218EFE9E00674D36 /* Build configuration list for PBXNativeTarget "XMTXCustomKeyBoardTests" */; 312 | buildPhases = ( 313 | F7A264B3218EFE9E00674D36 /* Sources */, 314 | F7A264B4218EFE9E00674D36 /* Frameworks */, 315 | F7A264B5218EFE9E00674D36 /* Resources */, 316 | ); 317 | buildRules = ( 318 | ); 319 | dependencies = ( 320 | F7A264B9218EFE9E00674D36 /* PBXTargetDependency */, 321 | ); 322 | name = XMTXCustomKeyBoardTests; 323 | productName = XMTXCustomKeyBoardTests; 324 | productReference = F7A264B7218EFE9E00674D36 /* XMTXCustomKeyBoardTests.xctest */; 325 | productType = "com.apple.product-type.bundle.unit-test"; 326 | }; 327 | F7A264C1218EFE9E00674D36 /* XMTXCustomKeyBoardUITests */ = { 328 | isa = PBXNativeTarget; 329 | buildConfigurationList = F7A264D1218EFE9E00674D36 /* Build configuration list for PBXNativeTarget "XMTXCustomKeyBoardUITests" */; 330 | buildPhases = ( 331 | F7A264BE218EFE9E00674D36 /* Sources */, 332 | F7A264BF218EFE9E00674D36 /* Frameworks */, 333 | F7A264C0218EFE9E00674D36 /* Resources */, 334 | ); 335 | buildRules = ( 336 | ); 337 | dependencies = ( 338 | F7A264C4218EFE9E00674D36 /* PBXTargetDependency */, 339 | ); 340 | name = XMTXCustomKeyBoardUITests; 341 | productName = XMTXCustomKeyBoardUITests; 342 | productReference = F7A264C2218EFE9E00674D36 /* XMTXCustomKeyBoardUITests.xctest */; 343 | productType = "com.apple.product-type.bundle.ui-testing"; 344 | }; 345 | /* End PBXNativeTarget section */ 346 | 347 | /* Begin PBXProject section */ 348 | F7A26497218EFE9E00674D36 /* Project object */ = { 349 | isa = PBXProject; 350 | attributes = { 351 | LastUpgradeCheck = 0920; 352 | ORGANIZATIONNAME = "风吹裤衩"; 353 | TargetAttributes = { 354 | F7A2649E218EFE9E00674D36 = { 355 | CreatedOnToolsVersion = 9.2; 356 | DevelopmentTeam = XZ557WUPWQ; 357 | ProvisioningStyle = Automatic; 358 | }; 359 | F7A264B6218EFE9E00674D36 = { 360 | CreatedOnToolsVersion = 9.2; 361 | DevelopmentTeam = HN267Y6RQZ; 362 | ProvisioningStyle = Automatic; 363 | TestTargetID = F7A2649E218EFE9E00674D36; 364 | }; 365 | F7A264C1218EFE9E00674D36 = { 366 | CreatedOnToolsVersion = 9.2; 367 | DevelopmentTeam = HN267Y6RQZ; 368 | ProvisioningStyle = Automatic; 369 | TestTargetID = F7A2649E218EFE9E00674D36; 370 | }; 371 | }; 372 | }; 373 | buildConfigurationList = F7A2649A218EFE9E00674D36 /* Build configuration list for PBXProject "XMTXCustomKeyBoard" */; 374 | compatibilityVersion = "Xcode 3.2"; 375 | developmentRegion = en; 376 | hasScannedForEncodings = 0; 377 | knownRegions = ( 378 | en, 379 | Base, 380 | ); 381 | mainGroup = F7A26496218EFE9E00674D36; 382 | productRefGroup = F7A264A0218EFE9E00674D36 /* Products */; 383 | projectDirPath = ""; 384 | projectRoot = ""; 385 | targets = ( 386 | F7A2649E218EFE9E00674D36 /* XMTXCustomKeyBoard */, 387 | F7A264B6218EFE9E00674D36 /* XMTXCustomKeyBoardTests */, 388 | F7A264C1218EFE9E00674D36 /* XMTXCustomKeyBoardUITests */, 389 | ); 390 | }; 391 | /* End PBXProject section */ 392 | 393 | /* Begin PBXResourcesBuildPhase section */ 394 | F7A2649D218EFE9E00674D36 /* Resources */ = { 395 | isa = PBXResourcesBuildPhase; 396 | buildActionMask = 2147483647; 397 | files = ( 398 | F7A264AF218EFE9E00674D36 /* LaunchScreen.storyboard in Resources */, 399 | F7A264AC218EFE9E00674D36 /* Assets.xcassets in Resources */, 400 | F7A264AA218EFE9E00674D36 /* Main.storyboard in Resources */, 401 | 237652E6219578AB00D8A021 /* KeyBoardSource.Bundle in Resources */, 402 | ); 403 | runOnlyForDeploymentPostprocessing = 0; 404 | }; 405 | F7A264B5218EFE9E00674D36 /* Resources */ = { 406 | isa = PBXResourcesBuildPhase; 407 | buildActionMask = 2147483647; 408 | files = ( 409 | ); 410 | runOnlyForDeploymentPostprocessing = 0; 411 | }; 412 | F7A264C0218EFE9E00674D36 /* Resources */ = { 413 | isa = PBXResourcesBuildPhase; 414 | buildActionMask = 2147483647; 415 | files = ( 416 | ); 417 | runOnlyForDeploymentPostprocessing = 0; 418 | }; 419 | /* End PBXResourcesBuildPhase section */ 420 | 421 | /* Begin PBXSourcesBuildPhase section */ 422 | F7A2649B218EFE9E00674D36 /* Sources */ = { 423 | isa = PBXSourcesBuildPhase; 424 | buildActionMask = 2147483647; 425 | files = ( 426 | 23581669219435B300CF8A77 /* XMTextField.m in Sources */, 427 | 23480D45219D1B3E0027A03F /* CarContentKeyBoard.m in Sources */, 428 | F7A26550218F0AFF00674D36 /* UIView+XMFrame.m in Sources */, 429 | F7A264A7218EFE9E00674D36 /* ViewController.m in Sources */, 430 | F7A26551218F0AFF00674D36 /* XMNumberkeyBoard.m in Sources */, 431 | F7A26553218F0AFF00674D36 /* XMNumStrongKeyBoard.m in Sources */, 432 | F7A26554218F0AFF00674D36 /* XMKeyBoardView.m in Sources */, 433 | 23554DC12199105700474124 /* XMCharKeyBoardView.m in Sources */, 434 | F7A264B2218EFE9E00674D36 /* main.m in Sources */, 435 | 23480D48219D56950027A03F /* UITextField+CHTHealper.m in Sources */, 436 | F7A264A4218EFE9E00674D36 /* AppDelegate.m in Sources */, 437 | F7A26552218F0AFF00674D36 /* XMWordKeyBoardView.m in Sources */, 438 | F7A2654F218F0AFF00674D36 /* XMBasekeyBoardView.m in Sources */, 439 | F7D027E12197DFBC002D2CDF /* XMNumberKeyBoardStyleOne.m in Sources */, 440 | 235A42F6219A75D400747141 /* XMCarNumHeaderKeyBoard.m in Sources */, 441 | ); 442 | runOnlyForDeploymentPostprocessing = 0; 443 | }; 444 | F7A264B3218EFE9E00674D36 /* Sources */ = { 445 | isa = PBXSourcesBuildPhase; 446 | buildActionMask = 2147483647; 447 | files = ( 448 | F7A264BC218EFE9E00674D36 /* XMTXCustomKeyBoardTests.m in Sources */, 449 | ); 450 | runOnlyForDeploymentPostprocessing = 0; 451 | }; 452 | F7A264BE218EFE9E00674D36 /* Sources */ = { 453 | isa = PBXSourcesBuildPhase; 454 | buildActionMask = 2147483647; 455 | files = ( 456 | F7A264C7218EFE9E00674D36 /* XMTXCustomKeyBoardUITests.m in Sources */, 457 | ); 458 | runOnlyForDeploymentPostprocessing = 0; 459 | }; 460 | /* End PBXSourcesBuildPhase section */ 461 | 462 | /* Begin PBXTargetDependency section */ 463 | F7A264B9218EFE9E00674D36 /* PBXTargetDependency */ = { 464 | isa = PBXTargetDependency; 465 | target = F7A2649E218EFE9E00674D36 /* XMTXCustomKeyBoard */; 466 | targetProxy = F7A264B8218EFE9E00674D36 /* PBXContainerItemProxy */; 467 | }; 468 | F7A264C4218EFE9E00674D36 /* PBXTargetDependency */ = { 469 | isa = PBXTargetDependency; 470 | target = F7A2649E218EFE9E00674D36 /* XMTXCustomKeyBoard */; 471 | targetProxy = F7A264C3218EFE9E00674D36 /* PBXContainerItemProxy */; 472 | }; 473 | /* End PBXTargetDependency section */ 474 | 475 | /* Begin PBXVariantGroup section */ 476 | F7A264A8218EFE9E00674D36 /* Main.storyboard */ = { 477 | isa = PBXVariantGroup; 478 | children = ( 479 | F7A264A9218EFE9E00674D36 /* Base */, 480 | ); 481 | name = Main.storyboard; 482 | sourceTree = ""; 483 | }; 484 | F7A264AD218EFE9E00674D36 /* LaunchScreen.storyboard */ = { 485 | isa = PBXVariantGroup; 486 | children = ( 487 | F7A264AE218EFE9E00674D36 /* Base */, 488 | ); 489 | name = LaunchScreen.storyboard; 490 | sourceTree = ""; 491 | }; 492 | /* End PBXVariantGroup section */ 493 | 494 | /* Begin XCBuildConfiguration section */ 495 | F7A264C9218EFE9E00674D36 /* Debug */ = { 496 | isa = XCBuildConfiguration; 497 | buildSettings = { 498 | ALWAYS_SEARCH_USER_PATHS = NO; 499 | CLANG_ANALYZER_NONNULL = YES; 500 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 501 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 502 | CLANG_CXX_LIBRARY = "libc++"; 503 | CLANG_ENABLE_MODULES = YES; 504 | CLANG_ENABLE_OBJC_ARC = YES; 505 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 506 | CLANG_WARN_BOOL_CONVERSION = YES; 507 | CLANG_WARN_COMMA = YES; 508 | CLANG_WARN_CONSTANT_CONVERSION = YES; 509 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 510 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 511 | CLANG_WARN_EMPTY_BODY = YES; 512 | CLANG_WARN_ENUM_CONVERSION = YES; 513 | CLANG_WARN_INFINITE_RECURSION = YES; 514 | CLANG_WARN_INT_CONVERSION = YES; 515 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 516 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 517 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 518 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 519 | CLANG_WARN_STRICT_PROTOTYPES = YES; 520 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 521 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 522 | CLANG_WARN_UNREACHABLE_CODE = YES; 523 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 524 | CODE_SIGN_IDENTITY = "iPhone Developer"; 525 | COPY_PHASE_STRIP = NO; 526 | DEBUG_INFORMATION_FORMAT = dwarf; 527 | ENABLE_STRICT_OBJC_MSGSEND = YES; 528 | ENABLE_TESTABILITY = YES; 529 | GCC_C_LANGUAGE_STANDARD = gnu11; 530 | GCC_DYNAMIC_NO_PIC = NO; 531 | GCC_NO_COMMON_BLOCKS = YES; 532 | GCC_OPTIMIZATION_LEVEL = 0; 533 | GCC_PREPROCESSOR_DEFINITIONS = ( 534 | "DEBUG=1", 535 | "$(inherited)", 536 | ); 537 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 538 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 539 | GCC_WARN_UNDECLARED_SELECTOR = YES; 540 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 541 | GCC_WARN_UNUSED_FUNCTION = YES; 542 | GCC_WARN_UNUSED_VARIABLE = YES; 543 | IPHONEOS_DEPLOYMENT_TARGET = 11.2; 544 | MTL_ENABLE_DEBUG_INFO = YES; 545 | ONLY_ACTIVE_ARCH = YES; 546 | SDKROOT = iphoneos; 547 | }; 548 | name = Debug; 549 | }; 550 | F7A264CA218EFE9E00674D36 /* Release */ = { 551 | isa = XCBuildConfiguration; 552 | buildSettings = { 553 | ALWAYS_SEARCH_USER_PATHS = NO; 554 | CLANG_ANALYZER_NONNULL = YES; 555 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 556 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 557 | CLANG_CXX_LIBRARY = "libc++"; 558 | CLANG_ENABLE_MODULES = YES; 559 | CLANG_ENABLE_OBJC_ARC = YES; 560 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 561 | CLANG_WARN_BOOL_CONVERSION = YES; 562 | CLANG_WARN_COMMA = YES; 563 | CLANG_WARN_CONSTANT_CONVERSION = YES; 564 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 565 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 566 | CLANG_WARN_EMPTY_BODY = YES; 567 | CLANG_WARN_ENUM_CONVERSION = YES; 568 | CLANG_WARN_INFINITE_RECURSION = YES; 569 | CLANG_WARN_INT_CONVERSION = YES; 570 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 571 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 572 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 573 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 574 | CLANG_WARN_STRICT_PROTOTYPES = YES; 575 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 576 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 577 | CLANG_WARN_UNREACHABLE_CODE = YES; 578 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 579 | CODE_SIGN_IDENTITY = "iPhone Developer"; 580 | COPY_PHASE_STRIP = NO; 581 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 582 | ENABLE_NS_ASSERTIONS = NO; 583 | ENABLE_STRICT_OBJC_MSGSEND = YES; 584 | GCC_C_LANGUAGE_STANDARD = gnu11; 585 | GCC_NO_COMMON_BLOCKS = YES; 586 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 587 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 588 | GCC_WARN_UNDECLARED_SELECTOR = YES; 589 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 590 | GCC_WARN_UNUSED_FUNCTION = YES; 591 | GCC_WARN_UNUSED_VARIABLE = YES; 592 | IPHONEOS_DEPLOYMENT_TARGET = 11.2; 593 | MTL_ENABLE_DEBUG_INFO = NO; 594 | SDKROOT = iphoneos; 595 | VALIDATE_PRODUCT = YES; 596 | }; 597 | name = Release; 598 | }; 599 | F7A264CC218EFE9E00674D36 /* Debug */ = { 600 | isa = XCBuildConfiguration; 601 | buildSettings = { 602 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 603 | CODE_SIGN_STYLE = Automatic; 604 | DEVELOPMENT_TEAM = XZ557WUPWQ; 605 | INFOPLIST_FILE = XMTXCustomKeyBoard/Info.plist; 606 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 607 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 608 | PRODUCT_BUNDLE_IDENTIFIER = com.cgm.XMTXCustomKeyBoard; 609 | PRODUCT_NAME = "$(TARGET_NAME)"; 610 | TARGETED_DEVICE_FAMILY = "1,2"; 611 | }; 612 | name = Debug; 613 | }; 614 | F7A264CD218EFE9E00674D36 /* Release */ = { 615 | isa = XCBuildConfiguration; 616 | buildSettings = { 617 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 618 | CODE_SIGN_STYLE = Automatic; 619 | DEVELOPMENT_TEAM = XZ557WUPWQ; 620 | INFOPLIST_FILE = XMTXCustomKeyBoard/Info.plist; 621 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 622 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 623 | PRODUCT_BUNDLE_IDENTIFIER = com.cgm.XMTXCustomKeyBoard; 624 | PRODUCT_NAME = "$(TARGET_NAME)"; 625 | TARGETED_DEVICE_FAMILY = "1,2"; 626 | }; 627 | name = Release; 628 | }; 629 | F7A264CF218EFE9E00674D36 /* Debug */ = { 630 | isa = XCBuildConfiguration; 631 | buildSettings = { 632 | BUNDLE_LOADER = "$(TEST_HOST)"; 633 | CODE_SIGN_STYLE = Automatic; 634 | DEVELOPMENT_TEAM = HN267Y6RQZ; 635 | INFOPLIST_FILE = XMTXCustomKeyBoardTests/Info.plist; 636 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 637 | PRODUCT_BUNDLE_IDENTIFIER = com.cgm.XMTXCustomKeyBoardTests; 638 | PRODUCT_NAME = "$(TARGET_NAME)"; 639 | TARGETED_DEVICE_FAMILY = "1,2"; 640 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/XMTXCustomKeyBoard.app/XMTXCustomKeyBoard"; 641 | }; 642 | name = Debug; 643 | }; 644 | F7A264D0218EFE9E00674D36 /* Release */ = { 645 | isa = XCBuildConfiguration; 646 | buildSettings = { 647 | BUNDLE_LOADER = "$(TEST_HOST)"; 648 | CODE_SIGN_STYLE = Automatic; 649 | DEVELOPMENT_TEAM = HN267Y6RQZ; 650 | INFOPLIST_FILE = XMTXCustomKeyBoardTests/Info.plist; 651 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 652 | PRODUCT_BUNDLE_IDENTIFIER = com.cgm.XMTXCustomKeyBoardTests; 653 | PRODUCT_NAME = "$(TARGET_NAME)"; 654 | TARGETED_DEVICE_FAMILY = "1,2"; 655 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/XMTXCustomKeyBoard.app/XMTXCustomKeyBoard"; 656 | }; 657 | name = Release; 658 | }; 659 | F7A264D2218EFE9E00674D36 /* Debug */ = { 660 | isa = XCBuildConfiguration; 661 | buildSettings = { 662 | CODE_SIGN_STYLE = Automatic; 663 | DEVELOPMENT_TEAM = HN267Y6RQZ; 664 | INFOPLIST_FILE = XMTXCustomKeyBoardUITests/Info.plist; 665 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 666 | PRODUCT_BUNDLE_IDENTIFIER = com.cgm.XMTXCustomKeyBoardUITests; 667 | PRODUCT_NAME = "$(TARGET_NAME)"; 668 | TARGETED_DEVICE_FAMILY = "1,2"; 669 | TEST_TARGET_NAME = XMTXCustomKeyBoard; 670 | }; 671 | name = Debug; 672 | }; 673 | F7A264D3218EFE9E00674D36 /* Release */ = { 674 | isa = XCBuildConfiguration; 675 | buildSettings = { 676 | CODE_SIGN_STYLE = Automatic; 677 | DEVELOPMENT_TEAM = HN267Y6RQZ; 678 | INFOPLIST_FILE = XMTXCustomKeyBoardUITests/Info.plist; 679 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 680 | PRODUCT_BUNDLE_IDENTIFIER = com.cgm.XMTXCustomKeyBoardUITests; 681 | PRODUCT_NAME = "$(TARGET_NAME)"; 682 | TARGETED_DEVICE_FAMILY = "1,2"; 683 | TEST_TARGET_NAME = XMTXCustomKeyBoard; 684 | }; 685 | name = Release; 686 | }; 687 | /* End XCBuildConfiguration section */ 688 | 689 | /* Begin XCConfigurationList section */ 690 | F7A2649A218EFE9E00674D36 /* Build configuration list for PBXProject "XMTXCustomKeyBoard" */ = { 691 | isa = XCConfigurationList; 692 | buildConfigurations = ( 693 | F7A264C9218EFE9E00674D36 /* Debug */, 694 | F7A264CA218EFE9E00674D36 /* Release */, 695 | ); 696 | defaultConfigurationIsVisible = 0; 697 | defaultConfigurationName = Release; 698 | }; 699 | F7A264CB218EFE9E00674D36 /* Build configuration list for PBXNativeTarget "XMTXCustomKeyBoard" */ = { 700 | isa = XCConfigurationList; 701 | buildConfigurations = ( 702 | F7A264CC218EFE9E00674D36 /* Debug */, 703 | F7A264CD218EFE9E00674D36 /* Release */, 704 | ); 705 | defaultConfigurationIsVisible = 0; 706 | defaultConfigurationName = Release; 707 | }; 708 | F7A264CE218EFE9E00674D36 /* Build configuration list for PBXNativeTarget "XMTXCustomKeyBoardTests" */ = { 709 | isa = XCConfigurationList; 710 | buildConfigurations = ( 711 | F7A264CF218EFE9E00674D36 /* Debug */, 712 | F7A264D0218EFE9E00674D36 /* Release */, 713 | ); 714 | defaultConfigurationIsVisible = 0; 715 | defaultConfigurationName = Release; 716 | }; 717 | F7A264D1218EFE9E00674D36 /* Build configuration list for PBXNativeTarget "XMTXCustomKeyBoardUITests" */ = { 718 | isa = XCConfigurationList; 719 | buildConfigurations = ( 720 | F7A264D2218EFE9E00674D36 /* Debug */, 721 | F7A264D3218EFE9E00674D36 /* Release */, 722 | ); 723 | defaultConfigurationIsVisible = 0; 724 | defaultConfigurationName = Release; 725 | }; 726 | /* End XCConfigurationList section */ 727 | }; 728 | rootObject = F7A26497218EFE9E00674D36 /* Project object */; 729 | } 730 | -------------------------------------------------------------------------------- /XMTXCustomKeyBoard/XMTXCustomKeyBoard.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /XMTXCustomKeyBoard/XMTXCustomKeyBoard.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /XMTXCustomKeyBoard/XMTXCustomKeyBoard/.swift-version: -------------------------------------------------------------------------------- 1 | 2.3 2 | -------------------------------------------------------------------------------- /XMTXCustomKeyBoard/XMTXCustomKeyBoard/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // XMTXCustomKeyBoard 4 | // 5 | // Created by 风吹裤衩 on 2018/11/4. 6 | // Copyright © 2018年 风吹裤衩. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /XMTXCustomKeyBoard/XMTXCustomKeyBoard/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // XMTXCustomKeyBoard 4 | // 5 | // Created by 风吹裤衩 on 2018/11/4. 6 | // Copyright © 2018年 风吹裤衩. 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 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /XMTXCustomKeyBoard/XMTXCustomKeyBoard/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /XMTXCustomKeyBoard/XMTXCustomKeyBoard/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /XMTXCustomKeyBoard/XMTXCustomKeyBoard/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 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 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | -------------------------------------------------------------------------------- /XMTXCustomKeyBoard/XMTXCustomKeyBoard/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /XMTXCustomKeyBoard/XMTXCustomKeyBoard/UITextField+CHTHealper.h: -------------------------------------------------------------------------------- 1 | // 2 | // UITextField+CHTPositionChange.h 3 | // CHTTextFieldHealper 4 | // 5 | // Created by risenb_mac on 16/8/17. 6 | // Copyright © 2016年 risenb_mac. All rights reserved. 7 | // https://github.com/a1419430265/CHTTextFieldHealper 8 | 9 | #import 10 | 11 | @interface UITextField (CHTHealper) 12 | 13 | /** 14 | * 是否支持视图上移 15 | */ 16 | @property (nonatomic, assign) BOOL canMove; 17 | /** 18 | * 点击回收键盘、移动的视图,默认是当前控制器的view 19 | */ 20 | @property (nonatomic, strong) UIView *moveView; 21 | /** 22 | * textfield底部距离键盘顶部的距离 23 | */ 24 | @property (nonatomic, assign) CGFloat heightToKeyboard; 25 | 26 | @property (nonatomic, assign, readonly) CGFloat keyboardY; 27 | @property (nonatomic, assign, readonly) CGFloat keyboardHeight; 28 | @property (nonatomic, assign, readonly) CGFloat initialY; 29 | @property (nonatomic, assign, readonly) CGFloat totalHeight; 30 | @property (nonatomic, strong, readonly) UITapGestureRecognizer *tapGesture; 31 | @property (nonatomic, assign, readonly) BOOL hasContentOffset; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /XMTXCustomKeyBoard/XMTXCustomKeyBoard/UITextField+CHTHealper.m: -------------------------------------------------------------------------------- 1 | // 2 | // UITextField+CHTPositionChange.m 3 | // CHTTextFieldHealper 4 | // 5 | // Created by risenb_mac on 16/8/17. 6 | // Copyright © 2016年 risenb_mac. All rights reserved. 7 | // 8 | 9 | #import "UITextField+CHTHealper.h" 10 | #import 11 | 12 | static char canMoveKey; 13 | static char moveViewKey; 14 | static char heightToKeyboardKey; 15 | static char initialYKey; 16 | static char tapGestureKey; 17 | static char keyboardYKey; 18 | static char totalHeightKey; 19 | static char keyboardHeightKey; 20 | static char hasContentOffsetKey; 21 | 22 | @implementation UITextField (CHTHealper) 23 | @dynamic canMove; 24 | @dynamic moveView; 25 | @dynamic heightToKeyboard; 26 | @dynamic initialY; 27 | @dynamic tapGesture; 28 | @dynamic keyboardY; 29 | @dynamic totalHeight; 30 | @dynamic keyboardHeight; 31 | @dynamic hasContentOffset; 32 | 33 | + (void)load { 34 | static dispatch_once_t onceToken; 35 | dispatch_once(&onceToken, ^{ 36 | SEL systemSel = @selector(initWithFrame:); 37 | SEL mySel = @selector(setupInitWithFrame:); 38 | [self exchangeSystemSel:systemSel bySel:mySel]; 39 | 40 | SEL systemSel2 = @selector(becomeFirstResponder); 41 | SEL mySel2 = @selector(newBecomeFirstResponder); 42 | [self exchangeSystemSel:systemSel2 bySel:mySel2]; 43 | 44 | SEL systemSel3 = @selector(resignFirstResponder); 45 | SEL mySel3 = @selector(newResignFirstResponder); 46 | [self exchangeSystemSel:systemSel3 bySel:mySel3]; 47 | 48 | SEL systemSel4 = @selector(initWithCoder:); 49 | SEL mySel4 = @selector(setupInitWithCoder:); 50 | [self exchangeSystemSel:systemSel4 bySel:mySel4]; 51 | }); 52 | [super load]; 53 | } 54 | 55 | // 交换方法 56 | + (void)exchangeSystemSel:(SEL)systemSel bySel:(SEL)mySel { 57 | Method systemMethod = class_getInstanceMethod([self class], systemSel); 58 | Method myMethod = class_getInstanceMethod([self class], mySel); 59 | //首先动态添加方法,实现是被交换的方法,返回值表示添加成功还是失败 60 | BOOL isAdd = class_addMethod(self, systemSel, method_getImplementation(myMethod), method_getTypeEncoding(myMethod)); 61 | if (isAdd) { 62 | //如果成功,说明类中不存在这个方法的实现 63 | //将被交换方法的实现替换到这个并不存在的实现 64 | class_replaceMethod(self, mySel, method_getImplementation(systemMethod), method_getTypeEncoding(systemMethod)); 65 | }else{ 66 | //否则,交换两个方法的实现 67 | method_exchangeImplementations(systemMethod, myMethod); 68 | } 69 | } 70 | 71 | - (instancetype)setupInitWithCoder:(NSCoder *)aDecoder { 72 | [self setup]; 73 | return [self setupInitWithCoder:aDecoder]; 74 | } 75 | 76 | - (instancetype)setupInitWithFrame:(CGRect)frame { 77 | [self setup]; 78 | return [self setupInitWithFrame:frame]; 79 | } 80 | 81 | - (void)setup { 82 | self.heightToKeyboard = 10; 83 | self.canMove = YES; 84 | self.keyboardY = 0; 85 | self.totalHeight = 0; 86 | self.tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction)]; 87 | } 88 | 89 | - (void)showAction:(NSNotification *)sender { 90 | if (!self.canMove) { 91 | return; 92 | } 93 | self.keyboardY = [sender.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].origin.y; 94 | self.keyboardHeight = [sender.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height; 95 | [self keyboardDidShow]; 96 | } 97 | 98 | - (void)hideAction:(NSNotification *)sender { 99 | if (!self.canMove || self.keyboardY == 0) { 100 | return; 101 | } 102 | [self hideKeyBoard:0.25]; 103 | } 104 | 105 | - (void)keyboardDidShow { 106 | if (self.keyboardHeight == 0) { 107 | return; 108 | } 109 | CGFloat fieldYInWindow = [self convertPoint:self.bounds.origin toView:[UIApplication sharedApplication].keyWindow].y; 110 | CGFloat height = (fieldYInWindow + self.heightToKeyboard + self.frame.size.height) - self.keyboardY + 44; 111 | CGFloat moveHeight = height > 0 ? height : 0; 112 | 113 | [UIView animateWithDuration:0.25 animations:^{ 114 | if (self.hasContentOffset) { 115 | UIScrollView *scrollView = (UIScrollView *)self.moveView; 116 | scrollView.contentOffset = CGPointMake(scrollView.contentOffset.x, scrollView.contentOffset.y + moveHeight); 117 | } else { 118 | CGRect rect = self.moveView.frame; 119 | self.initialY = rect.origin.y; 120 | rect.origin.y -= moveHeight; 121 | self.moveView.frame = rect; 122 | } 123 | self.totalHeight += moveHeight; 124 | }]; 125 | } 126 | 127 | - (void)hideKeyBoard:(CGFloat)duration { 128 | [UIView animateWithDuration:duration animations:^{ 129 | if (self.hasContentOffset) { 130 | UIScrollView *scrollView = (UIScrollView *)self.moveView; 131 | scrollView.contentOffset = CGPointMake(scrollView.contentOffset.x, scrollView.contentOffset.y - self.totalHeight); 132 | } else { 133 | CGRect rect = self.moveView.frame; 134 | rect.origin.y += self.totalHeight; 135 | self.moveView.frame = rect; 136 | } 137 | self.totalHeight = 0; 138 | }]; 139 | } 140 | ///< 弹 141 | - (BOOL)newBecomeFirstResponder { 142 | if (self.moveView == nil) { 143 | self.moveView = [self viewController].view; 144 | } 145 | if (![self.moveView.gestureRecognizers containsObject:self.tapGesture]) { 146 | [self.moveView addGestureRecognizer:self.tapGesture]; 147 | } 148 | if ([self isFirstResponder] || !self.canMove) { 149 | return [self newBecomeFirstResponder]; 150 | } 151 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(showAction:) name:UIKeyboardWillShowNotification object:nil]; 152 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(hideAction:) name:UIKeyboardWillHideNotification object:nil]; 153 | return [self newBecomeFirstResponder]; 154 | } 155 | ///< 收 156 | - (BOOL)newResignFirstResponder { 157 | if ([self.moveView.gestureRecognizers containsObject:self.tapGesture]) { 158 | [self.moveView removeGestureRecognizer:self.tapGesture]; 159 | } 160 | if (!self.canMove) { 161 | return [self newResignFirstResponder]; 162 | } 163 | BOOL result = [self newResignFirstResponder]; 164 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil]; 165 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil]; 166 | [self hideKeyBoard:0]; 167 | return result; 168 | } 169 | 170 | - (void)tapAction { 171 | [[self viewController].view endEditing:YES]; 172 | } 173 | 174 | - (UIViewController *)viewController { 175 | UIView *next = self; 176 | while (1) { 177 | UIResponder *nextResponder = [next nextResponder]; 178 | if ([nextResponder isKindOfClass:[UIViewController class]]) { 179 | return (UIViewController *)nextResponder; 180 | }else if ([nextResponder isKindOfClass:[UIWindow class]]){ 181 | return nil; 182 | } 183 | next = next.superview; 184 | } 185 | return nil; 186 | } 187 | 188 | - (void)setCanMove:(BOOL)canMove { 189 | objc_setAssociatedObject(self, &canMoveKey, @(canMove), OBJC_ASSOCIATION_RETAIN_NONATOMIC); 190 | } 191 | 192 | - (BOOL)canMove { 193 | return [objc_getAssociatedObject(self, &canMoveKey) boolValue]; 194 | } 195 | 196 | - (void)setHeightToKeyboard:(CGFloat)heightToKeyboard { 197 | objc_setAssociatedObject(self, &heightToKeyboardKey, @(heightToKeyboard), OBJC_ASSOCIATION_RETAIN_NONATOMIC); 198 | } 199 | 200 | - (CGFloat)heightToKeyboard { 201 | return [objc_getAssociatedObject(self, &heightToKeyboardKey) floatValue]; 202 | } 203 | 204 | - (void)setMoveView:(UIView *)moveView { 205 | self.hasContentOffset = NO; 206 | if ([moveView isKindOfClass:[UIScrollView class]]) { 207 | self.hasContentOffset = YES; 208 | } 209 | 210 | objc_setAssociatedObject(self, &moveViewKey, moveView, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 211 | } 212 | 213 | - (UIView *)moveView { 214 | return objc_getAssociatedObject(self, &moveViewKey); 215 | } 216 | 217 | - (void)setInitialY:(CGFloat)initialY { 218 | objc_setAssociatedObject(self, &initialYKey, @(initialY), OBJC_ASSOCIATION_RETAIN_NONATOMIC); 219 | } 220 | 221 | - (CGFloat)initialY { 222 | return [objc_getAssociatedObject(self, &initialYKey) floatValue]; 223 | } 224 | 225 | - (void)setTapGesture:(UITapGestureRecognizer *)tapGesture { 226 | objc_setAssociatedObject(self, &tapGestureKey, tapGesture, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 227 | } 228 | 229 | - (UITapGestureRecognizer *)tapGesture { 230 | return objc_getAssociatedObject(self, &tapGestureKey); 231 | } 232 | 233 | - (void)setKeyboardY:(CGFloat)keyboardY { 234 | objc_setAssociatedObject(self, &keyboardYKey, @(keyboardY), OBJC_ASSOCIATION_RETAIN_NONATOMIC); 235 | } 236 | 237 | - (CGFloat)keyboardY { 238 | return [objc_getAssociatedObject(self, &keyboardYKey) floatValue]; 239 | } 240 | 241 | - (void)setTotalHeight:(CGFloat)totalHeight { 242 | objc_setAssociatedObject(self, &totalHeightKey, @(totalHeight), OBJC_ASSOCIATION_RETAIN_NONATOMIC); 243 | } 244 | 245 | - (CGFloat)totalHeight { 246 | return [objc_getAssociatedObject(self, &totalHeightKey) floatValue]; 247 | } 248 | 249 | - (void)setKeyboardHeight:(CGFloat)keyboardHeight { 250 | objc_setAssociatedObject(self, &keyboardHeightKey, @(keyboardHeight), OBJC_ASSOCIATION_RETAIN_NONATOMIC); 251 | } 252 | 253 | - (CGFloat)keyboardHeight { 254 | return [objc_getAssociatedObject(self, &keyboardHeightKey) floatValue]; 255 | } 256 | 257 | - (void)setHasContentOffset:(BOOL)hasContentOffset { 258 | objc_setAssociatedObject(self, &hasContentOffsetKey, @(hasContentOffset), OBJC_ASSOCIATION_RETAIN_NONATOMIC); 259 | } 260 | 261 | - (BOOL)hasContentOffset { 262 | return [objc_getAssociatedObject(self, &hasContentOffsetKey) boolValue]; 263 | } 264 | 265 | @end 266 | -------------------------------------------------------------------------------- /XMTXCustomKeyBoard/XMTXCustomKeyBoard/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // XMTXCustomKeyBoard 4 | // 5 | // Created by 风吹裤衩 on 2018/11/4. 6 | // Copyright © 2018年 风吹裤衩. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /XMTXCustomKeyBoard/XMTXCustomKeyBoard/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // XMTXCustomKeyBoard 4 | // 5 | // Created by 风吹裤衩 on 2018/11/4. 6 | // Copyright © 2018年 风吹裤衩. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "XMTextField.h" 11 | 12 | @interface ViewController () 13 | 14 | @property (weak, nonatomic) IBOutlet XMTextField *textfileOne; 15 | @property (weak, nonatomic) IBOutlet XMTextField *textfileTwo; 16 | @property (weak, nonatomic) IBOutlet XMTextField *textfileThree; 17 | @property (weak, nonatomic) IBOutlet XMTextField *textfileFour; 18 | @property (weak, nonatomic) IBOutlet XMTextField *textfileFive; 19 | @property (weak, nonatomic) IBOutlet XMTextField *textfileSix; 20 | @property (weak, nonatomic) IBOutlet XMTextField *textfileSeven; 21 | @property (weak, nonatomic) IBOutlet XMTextField *textfileEight; 22 | @property (weak, nonatomic) IBOutlet XMTextField *textfileNine; 23 | 24 | @end 25 | 26 | @implementation ViewController 27 | 28 | - (void)viewDidLoad { 29 | [super viewDidLoad]; 30 | // Do any additional setup after loading the view, typically from a nib. 31 | 32 | self.textfileOne.xmKeyBoardType = XMkeyBoardType_OnlyNumber; 33 | self.textfileTwo.xmKeyBoardType = XMkeyBoardType_NumberStyleOne; 34 | self.textfileThree.xmKeyBoardType = XMkeyBoardType_StrongNumber; 35 | self.textfileFour.xmKeyBoardType = XMkeyBoardType_IDCardNumber; 36 | self.textfileFive.xmKeyBoardType = XMkeyBoardType_Word; 37 | self.textfileSix.xmKeyBoardType = XMkeyBoardType_charAndNumber; 38 | self.textfileSeven.xmKeyBoardType = XMkeyBoardType_RandomNumber; 39 | self.textfileEight.xmKeyBoardType = XMkeyBoardType_CarNumHeader; 40 | self.textfileNine.xmKeyBoardType = XMkeyBoardType_Default; 41 | 42 | 43 | ///第一个输入框限制长度 为5 44 | self.textfileOne.maxInpuptLenth = 5; 45 | 46 | ///输入回调 47 | self.textfileOne.inputTextBlock = ^(id userInfo) { 48 | XMTextField *tf = (XMTextField *)userInfo; 49 | XMLog(@"tf.text = %@",tf.text); 50 | }; 51 | } 52 | 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /XMTXCustomKeyBoard/XMTXCustomKeyBoard/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // XMTXCustomKeyBoard 4 | // 5 | // Created by 风吹裤衩 on 2018/11/4. 6 | // Copyright © 2018年 风吹裤衩. 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 | -------------------------------------------------------------------------------- /XMTXCustomKeyBoard/XMTXCustomKeyBoardTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /XMTXCustomKeyBoard/XMTXCustomKeyBoardTests/XMTXCustomKeyBoardTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // XMTXCustomKeyBoardTests.m 3 | // XMTXCustomKeyBoardTests 4 | // 5 | // Created by 风吹裤衩 on 2018/11/4. 6 | // Copyright © 2018年 风吹裤衩. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface XMTXCustomKeyBoardTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation XMTXCustomKeyBoardTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /XMTXCustomKeyBoard/XMTXCustomKeyBoardUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /XMTXCustomKeyBoard/XMTXCustomKeyBoardUITests/XMTXCustomKeyBoardUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // XMTXCustomKeyBoardUITests.m 3 | // XMTXCustomKeyBoardUITests 4 | // 5 | // Created by 风吹裤衩 on 2018/11/4. 6 | // Copyright © 2018年 风吹裤衩. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface XMTXCustomKeyBoardUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation XMTXCustomKeyBoardUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | --------------------------------------------------------------------------------