Sian 发表于 2015-5-20 13:33:28

iOS制作自定义数字键盘

一、应用场景

       很多情况下我们的输入都是有硬性要求的,比如只能输入数字,通常情况下我们的解决方案就是指定输入框的键盘模式(keyboardType),可系统提供给我的键盘种类还是非常有限的,如下所示:
typedef NS_ENUM(NSInteger, UIKeyboardType) {
    UIKeyboardTypeDefault,                // Default type for the current input method.
    UIKeyboardTypeASCIICapable,         // Displays a keyboard which can enter ASCII characters, non-ASCII keyboards remain active
    UIKeyboardTypeNumbersAndPunctuation,// Numbers and assorted punctuation.
    UIKeyboardTypeURL,                  // A type optimized for URL entry (shows . / .com prominently).
    UIKeyboardTypeNumberPad,            // A number pad (0-9). Suitable for PIN entry.
    UIKeyboardTypePhonePad,               // A phone pad (1-9, *, 0, #, with letters under the numbers).
    UIKeyboardTypeNamePhonePad,         // A type optimized for entering a person's name or phone number.
    UIKeyboardTypeEmailAddress,         // A type optimized for multiple email address entry (shows space @ . prominently).
    UIKeyboardTypeDecimalPad NS_ENUM_AVAILABLE_IOS(4_1),   // A number pad with a decimal point.
    UIKeyboardTypeTwitter NS_ENUM_AVAILABLE_IOS(5_0),      // A type optimized for twitter text entry (easy access to @ #)
    UIKeyboardTypeWebSearch NS_ENUM_AVAILABLE_IOS(7_0),    // A default keyboard type with URL-oriented addition (shows space . prominently).

    UIKeyboardTypeAlphabet = UIKeyboardTypeASCIICapable, // Deprecated

};有时候可能不能满足我们的需要,比如在数字键盘中需要增加一个完成按钮等等,我们在现有的键盘上动手脚都无法完美解决我们所遇到的问题,最好的办法就是自定义一个符合我们需求的键盘。

二、示例效果


如何能实现这种效果呢,其实使用非常简单,就一行代码:
self.textField.keyboardType = SAKeyboardTypeNumber;
三、设计原理

       类似于UITextField这样的文本输入控件,一般都有一个inputView属性,这个属性就是用来指定自定义键盘的,还有一个inputAccessoryView属性,用来在键盘上方增加自定义的工具条或控件,我们自定义键盘就从inputView这个属性上做文章。
       然而在使用的时候,我又希望能保持系统风格,即通过setKeyboardType:这个方法,或者改变keyboardType这个枚举值来达到指定自定义键盘的目的,看起来一切都是那么的自然,就好像扩展了系统键盘类型这种效果,我个人认为这种封装是最好的,不用改变开发者的使用习惯!
       由于要改变setKeyboardType:这个方法,无法通过Category实现,只能自定义一个TextField继承自UITextField来覆盖这个方法,如果不想这样做,那就只能通过inputView属性来实现,我这里只介绍前者,我认为重写没什么不好,并且项目上很多系统的类都是需要重写的,重写可以统一风格,统一调整,重写还可以积累自己的一些好用的东西,最终可以积累出一个属于自己的库!
       另外一点,这个键盘需要事先通过xib画好,每一个键可以使用按钮来实现,排版布局这里不做太多说明,实现输入则是调用TextField的replaceRange:withText这个就去来实现      

四、代码说明

1、SATextField.h
//
//SATextField.h
//Test
//
//Created by 余西安 on 15/5/16.
//Copyright (c) 2015年 Sian. All rights reserved.
//
typedef enum {
    SAKeyboardTypeNumber
}SAKeyboardType;

#import <UIKit/UIKit.h>

@interface SATextField : UITextField

- (void)setKeyboardType:(SAKeyboardType)keyboardType;

@end
2、SATextField.m
//
//SATextField.m
//Test
//
//Created by 余西安 on 15/5/16.
//Copyright (c) 2015年 Sian. All rights reserved.
//

#import "SATextField.h"
#import "SANumberKeyboard.h"

@implementation SATextField

- (void)setKeyboardType:(SAKeyboardType)keyboardType
{
    switch (keyboardType) {
      case SAKeyboardTypeNumber:{
            SANumberKeyboard *keyboard = ;
            self.inputView = keyboard;
            
      }break;
            
      default: ; break;
    }
}

@end
3、SANumberKeyboard.h
//
//SANumberKeyboard.h
//Test
//
//Created by 余西安 on 15/5/16.
//Copyright (c) 2015年 Sian. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "SATextField.h"

@interface SANumberKeyboard : UIView

@property (nonatomic, weak) SATextField *textField;

+ (instancetype)keyboardWithTextField:(SATextField *)textField;

@end
4、SANumberKeyboard.m
//
//SANumberKeyboard.m
//Test
//
//Created by 余西安 on 15/5/16.
//Copyright (c) 2015年 Sian. All rights reserved.
//

#import "SANumberKeyboard.h"

@implementation SANumberKeyboard

+ (instancetype)keyboardWithTextField:(SATextField *)textField;
{
    SANumberKeyboard *keyboard = [ init];
    keyboard.textField = textField;
    return keyboard;
}

- (instancetype)init
{
    self = [[ loadNibNamed:@"SANumberKeyboard" owner:nil options:nil] firstObject];
    for (UIButton *btn in self.subviews) {
      if (btn.tag == 0) continue;
      UIImage *image = ];
      UIImage *image1 = ];
      if (btn.tag <= 10);
      if (btn.tag > 10);
      ;
    }
    return self;
}

/// 指定颜色生成一张大小为(1,1)的图片
- (UIImage *)imageWithColor:(UIColor *)color
{
    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
   
    CGContextSetFillColorWithColor(context, );
    CGContextFillRect(context, rect);
   
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
   
    return image;
}

/// 各按键事件
- (void)buttonEven:(UIButton *)button
{
    UITextRange *textRange = self.textField.selectedTextRange;
    NSString *string = @"";
    switch (button.tag) {
      case1: string = @"1"; break;
      case2: string = @"2"; break;
      case3: string = @"3"; break;
      case4: string = @"4"; break;
      case5: string = @"5"; break;
      case6: string = @"6"; break;
      case7: string = @"7"; break;
      case8: string = @"8"; break;
      case9: string = @"9"; break;
      case 10: string = @"0"; break;
      case 11: string = @"."; break;
      case 12:{
            if (textRange.isEmpty){
                UITextPosition *from = ;
                UITextPosition *to = ;
                textRange = ;
            }
      }break;
      default:break;
    }
    ;
}

@end
五、源码下载(Demo)
**** Hidden Message *****
该控件纯属抛砖引玉,通过这种思路能做的事情还非常的多!!

zj0517 发表于 2015-5-20 15:01:34

不错,只要有时间每天都会登陆支持一下!:lol

喵了个咪 发表于 2015-6-18 08:56:11

挺好的!!!!

活在梦里丶 发表于 2015-6-26 15:19:34

学习大神的思路

vidonia0803 发表于 2016-7-6 10:23:56

封装好一劳永逸
页: [1]
查看完整版本: iOS制作自定义数字键盘