iOS 車牌號輸入鍵盤PlateKeyBoard

重點:

通過替換UITextField的inputView展示自定義鍵盤

獲取當前系統響應鏈第一響應者:

UIResponder並沒有提供直接獲取的方法、這裏調用sendAction:to:from:forEvent:方法。

當target爲空時、系統會遍歷響應鏈由第一響應者響應事件,這樣我們就獲取到第一響應者。

我們通過獲取到的responder實現鍵盤數字的輸入及退格操作

複製粘貼時鍵盤的切換鍵鈕狀態:

通過UIControlEventEditingChanged獲取鍵盤點擊後輸入框內容的改變

在textField:shouldChangeCharactersInRange:replacementString:獲取複製粘貼內容及進行規則判斷

//ViewController.m

#import "ViewController.h"
#import "PlateInputView.h"

#define WIDTH [UIScreen mainScreen].bounds.size.width
#define HEIGHT [UIScreen mainScreen].bounds.size.height


@interface ViewController ()<UITextFieldDelegate>


@property (nonatomic,strong)PlateInputView * plateInput;
@property (nonatomic,strong)UITextField * plateTextField;


@end

@implementation ViewController

- (void)viewDidLoad {
   [super viewDidLoad];
   
   _plateTextField = [[UITextField alloc]initWithFrame:CGRectMake(30, 100, WIDTH-60, 50)];
   _plateTextField.delegate = self;
   _plateTextField.layer.borderColor = [UIColor blackColor].CGColor;
   _plateTextField.layer.borderWidth = 1;
   _plateTextField.keyboardType = UIKeyboardTypeNumberPad;//設置數字鍵盤防止複製粘貼板自動加空格
   __block ViewController * weakSelf = self;
   _plateInput = [[PlateInputView alloc]init];
   _plateInput.sendTextBlock = ^(NSString *palteString) {
       weakSelf.plateTextField.text = palteString;
   };
   
   _plateTextField.inputView = _plateInput;
   [_plateTextField addTarget:self action:@selector(textChange:) forControlEvents:UIControlEventEditingChanged];
   [self.view addSubview:_plateTextField];
   
   
   UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapClick:)];
   [self.view addGestureRecognizer:tap];
   // Do any additional setup after loading the view, typically from a nib.
}

#pragma mark 車牌號輸入框監聽及代理方法

-(void)textChange:(UITextField *)textField{
   NSString * str = textField.text;
   _plateInput.plateStr = str;
}
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
   
   NSString * str = textField.text;
   
   string = [string stringByReplacingOccurrencesOfString:@" " withString:@""];
   str = [str stringByReplacingCharactersInRange:range withString:string];
   
   if (str.length>0) {
       NSArray * provinceArr = @[@"京",@"津",@"晉",@"冀",@"蒙",@"遼",@"黑",@"吉",@"滬",@"蘇",@"浙",@"皖",@"閩",@"贛",
                                 @"魯",@"豫",@"鄂",@"湘",@"粵",@"桂",@"瓊",@"渝",@"川",@"貴",@"雲",@"藏",@"陝",@"甘",
                                 @"青",@"寧",@"新",@"W"];
       
       if (str.length>8) {
           return NO;
       }else if (![provinceArr containsObject:[str substringToIndex:1]]) {
           return NO;
       }else{
           for (NSString * enumStr in provinceArr) {
               
               if ([enumStr isEqualToString:@"W"]) {
               
               }else if ([[str substringWithRange:NSMakeRange(1, str.length-1)] rangeOfString:enumStr].location != NSNotFound ) {
                   return NO;
               }
           }
       }
   }
   _plateInput.plateStr = str;
   
   return YES;
}

-(void)tapClick:(UITapGestureRecognizer *)tap{
   [tap.view endEditing:YES];
}

@end

PlateInputView

 //  PlateInputView.h 文件
 
@interface PlateInputView : UIInputView



@property (nonatomic,weak)id<UIKeyInput> keyInput;//接收響應者、處理輸入、退格
@property (nonatomic,strong)NSString *plateStr;

@property (nonatomic,copy)void (^sendTextBlock)(NSString *plateString);//第一位不是省份簡寫時輸入框回調

-(instancetype)init;



@end
 
 
 //   PlateKeyBoard.m
 
 
 #import "PlateInputView.h"


#define WIDTH [UIScreen mainScreen].bounds.size.width
#define HEIGHT [UIScreen mainScreen].bounds.size.height
#define INPUTHEIGHT 180 * (HEIGHT/568)


#pragma mark 獲取當前應用第一響應鏈對象
static __weak id firstResponder;
@implementation UIResponder(FirstResponder)


+ (id)firstResponder{
    firstResponder = nil;
    //當target爲空時、系統會默認遍歷響應鏈執行
    [[UIApplication sharedApplication] sendAction:@selector(findFirstResponder:) to:nil from:nil forEvent:nil];
    return firstResponder;
}
#pragma clang diagnostic pop

- (void)findFirstResponder:(id)sender{//第一響應者響應方法、設置firstResponder
    firstResponder = self;
}

@end




@interface PlateInputView ()

@property (nonatomic, strong) NSArray *provinceArr;//省份簡稱
@property (nonatomic, strong) NSArray *letterArr;//尾數(數字+字母)
@property (nonatomic, strong) UIView *provinceView;//省份選擇視圖
@property (nonatomic, strong) UIView *letterView;//尾數視圖
@end


@implementation PlateInputView


-(instancetype)init{
    if (self = [super init]) {
        [self createInputV];
    }
    return self;
}

-(void)createInputV{
    
    self.frame = CGRectMake(0, HEIGHT-INPUTHEIGHT, WIDTH, INPUTHEIGHT);
    self.backgroundColor = [UIColor lightGrayColor];
    
    _provinceArr = @[@"京",@"津",@"晉",@"冀",@"蒙",@"遼",@"黑",@"吉",@"滬",
                         @"蘇",@"浙",@"皖",@"閩",@"贛",@"魯",@"豫",@"鄂",@"湘",
                         @"粵",@"桂",@"瓊",@"渝",@"川",@"貴",@"雲",@"藏",@"陝",
                         @"甘",@"青",@"寧",@"新",@"W"];
    
    _letterArr = @[@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"0",
                       @"Q",@"W",@"E",@"R",@"T",@"Y",@"U",@"O",@"P",@"A",
                       @"S",@"D",@"F",@"G",@"H",@"J",@"K",@"L",@"學",@"Z",
                       @"X",@"C",@"V",@"B",@"N",@"M"];
    
    _provinceView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, WIDTH, INPUTHEIGHT)];
    [self addSubview:_provinceView];
    
    
    CGFloat provinceWidth = (WIDTH) / 9;//單行數量爲9時所佔寬度
    CGFloat provinceHeight = INPUTHEIGHT / 4;//單列數量爲4時所佔高度
    CGFloat provinceFrameX = 0.0;//
    
    for (int i = 0; i < _provinceArr.count+2; i++) {//數量+2爲後面添加刪除確定鍵預留
        UIButton *provinceBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        
        if (i < _provinceArr.count) {
            
            provinceBtn.frame = CGRectMake(1.5 + provinceWidth * (i%9), 1.5+ provinceHeight*(i/9), provinceWidth - 3, provinceHeight - 3);
            provinceBtn.backgroundColor = [UIColor whiteColor];
            
            [provinceBtn setTitle:_provinceArr[i] forState:0];
            [provinceBtn setTitleColor:[UIColor blackColor] forState:0];
            provinceFrameX = CGRectGetMaxX(provinceBtn.frame)+3;
            
        }else if(i == _provinceArr.count){
            
            provinceBtn.frame = CGRectMake(provinceFrameX, 1.5+ provinceHeight*(i/10), provinceWidth*1.5 - 3, provinceHeight - 3);
            provinceBtn.backgroundColor = [UIColor whiteColor];
            [provinceBtn setImage:[UIImage imageNamed:@"plateDelete"] forState:UIControlStateNormal];
            provinceFrameX = CGRectGetMaxX(provinceBtn.frame)+3;
            
        }else if(i == _provinceArr.count+1){
            provinceBtn.frame = CGRectMake(provinceFrameX, 1.5 + provinceHeight * 3, WIDTH-provinceFrameX- 1.5, provinceHeight - 3);
            provinceBtn.userInteractionEnabled = NO;
            provinceBtn.backgroundColor = [UIColor grayColor];
            [provinceBtn setTitle:@"確認" forState:0];
            [provinceBtn setTitleColor:[UIColor whiteColor] forState:0];
        }
        
        provinceBtn.layer.cornerRadius = 3;
        provinceBtn.tag = 1000 + i;
        [provinceBtn addTarget:self action:@selector(provinceClick:) forControlEvents:UIControlEventTouchUpInside];
        [_provinceView addSubview:provinceBtn];
    }
    
    
    
    UIView *letterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, WIDTH, INPUTHEIGHT)];
    letterView.hidden = YES;
    self.letterView = letterView;
    [self addSubview:letterView];
    
    CGFloat letterWidth = (WIDTH) / 10;
    CGFloat letterHeight = INPUTHEIGHT / 4;
    CGFloat letterFrameX = 0.0;
    for (int i = 0; i < _letterArr.count+2; i++) {
        UIButton *letterBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        if (i < _letterArr.count) {
            
            letterBtn.frame = CGRectMake(1.5 + letterWidth * (i%10), 1.5+ letterHeight*(i/10), letterWidth - 3, letterHeight - 3);
            letterBtn.backgroundColor = [UIColor whiteColor];
            
            [letterBtn setTitle:_letterArr[i] forState:0];
            [letterBtn setTitleColor:[UIColor blackColor] forState:0];
            letterFrameX = CGRectGetMaxX(letterBtn.frame)+3;
            
        }else if(i == _letterArr.count){
            
            letterBtn.frame = CGRectMake(letterFrameX, 1.5+ letterHeight*(i/10), letterWidth*1.5 - 3, letterHeight - 3);
            letterBtn.backgroundColor = [UIColor whiteColor];
            [letterBtn setImage:[UIImage imageNamed:@"plateDelete"] forState:UIControlStateNormal];
            letterFrameX = CGRectGetMaxX(letterBtn.frame)+3;
            
        }else if(i == _letterArr.count+1){
            letterBtn.frame = CGRectMake(letterFrameX, 1.5 + letterHeight * 3, WIDTH-letterFrameX- 1.5, letterHeight - 3);
            letterBtn.userInteractionEnabled = NO;
            letterBtn.backgroundColor = [UIColor grayColor];
            [letterBtn setTitle:@"確認" forState:0];
            [letterBtn setTitleColor:[UIColor whiteColor] forState:0];
        }
        
        letterBtn.layer.cornerRadius = 3;
        letterBtn.tag = 1000 + i;
        [letterBtn addTarget:self action:@selector(letterClick:) forControlEvents:UIControlEventTouchUpInside];
        [letterView addSubview:letterBtn];
    }
    
}

#pragma mark  省份點擊事件
- (void)provinceClick:(UIButton *)button{
    
    NSInteger index = button.tag-1000;
    if (index == 33){//確認
        [self putAway];
    }else if (index == 32){//   刪除
        [self deleteText];
    }else{
        
        if (_plateStr.length<8) {
            
            if (_plateStr.length>0) {
                NSArray * provinceArr = @[@"京",@"津",@"晉",@"冀",@"蒙",@"遼",@"黑",@"吉",@"滬",@"蘇",@"浙",@"皖",@"閩",@"贛",
                                          @"魯",@"豫",@"鄂",@"湘",@"粵",@"桂",@"瓊",@"渝",@"川",@"貴",@"雲",@"藏",@"陝",@"甘",
                                          @"青",@"寧",@"新",@"W"];
                
                if (![provinceArr containsObject:[_plateStr substringToIndex:1]]) {//當輸入框第一位不是省份時、拼接到第一位上、方式根據自己習慣調整
                    _plateStr = [NSString stringWithFormat:@"%@%@",button.titleLabel.text,_plateStr?:@""];
                    self.sendTextBlock(_plateStr);
                }
            }else{
                _plateStr = button.titleLabel.text;
                self.sendTextBlock(_plateStr);
            }
        }
        
        self.provinceView.hidden = YES;
        self.letterView.hidden = NO;
        
    }
}
#pragma mark 尾數點擊事件
- (void)letterClick:(UIButton *)button{
    
    NSInteger index = button.tag-1000;
    
    if (index == 37){//確認
        [self putAway];
    }else if (index == 36){//   刪除
        [self deleteText];
        
    }else{
        
        if (_plateStr.length<8) {
            id <UIKeyInput>keyInput = self.keyInput;
            [keyInput insertText:button.titleLabel.text];
        }
    }
}


#pragma mark 隱藏鍵盤
- (void)putAway{
    UIResponder *firstResponder = self.keyInput;
    if (firstResponder) {
        [firstResponder resignFirstResponder];
    }
}

#pragma mark 刪除數據
- (void)deleteText{
    
    id <UIKeyInput> keyInput = self.keyInput;
    [keyInput deleteBackward];
    
}

#pragma mark 外部設置輸入框文字時inputView處理

-(void)setPlateStr:(NSString *)plateStr{
    _plateStr = plateStr;
    
    if (plateStr.length>0) {
        
        NSArray * provinceArr = @[@"京",@"津",@"晉",@"冀",@"蒙",@"遼",@"黑",@"吉",@"滬",@"蘇",@"浙",@"皖",@"閩",@"贛",@"魯",
                                  @"豫",@"鄂",@"湘",@"粵",@"桂",@"瓊",@"渝",@"川",@"貴",@"雲",@"藏",@"陝",@"甘",@"青",@"寧",
                                  @"新",@"W"];
        
        if (![provinceArr containsObject:[plateStr substringToIndex:1]]) {
            self.provinceView.hidden = NO;
            self.letterView.hidden = YES;
        }else{
            self.provinceView.hidden = YES;
            self.letterView.hidden = NO;
        }
    }else{
        self.provinceView.hidden = NO;
        self.letterView.hidden = YES;
    }
    
    if (plateStr.length>6) {
        
        UIButton * button = (UIButton *)[self.provinceView viewWithTag:1033];
        button.userInteractionEnabled = YES;
        button.backgroundColor = [UIColor blueColor];
        
        UIButton * button2 = (UIButton *)[self.letterView viewWithTag:1037];
        button2.userInteractionEnabled = YES;
        button2.backgroundColor = [UIColor blueColor];
        
        
    }else{
        UIButton * button = (UIButton *)[self.provinceView viewWithTag:1033];
        button.userInteractionEnabled = NO;
        button.backgroundColor = [UIColor grayColor];
        
        UIButton * button2 = (UIButton *)[self.letterView viewWithTag:1037];
        button2.userInteractionEnabled = NO;
        button2.backgroundColor = [UIColor grayColor];
        
    }
    
}


- (id<UIKeyInput>)keyInput{
    
    id <UIKeyInput> keyInput = _keyInput;
    if (keyInput) {
        return keyInput;
    }
    keyInput = [UIResponder firstResponder];
    
    if (![keyInput conformsToProtocol:@protocol(UITextInput)]) {
        return nil;
    }
    _keyInput = keyInput;
    return keyInput;
}



/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

@end
 
 

項目地址

Git首頁

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章