深入讲解iOS键盘三:自定义键盘的两种方法

本系列博客是本人的开发笔记。为了方便讨论,本人新建了一个微信群(iOS技术讨论群),想要加入的,请添加本人微信:zhujinhui207407,【加我前请备注:iOS 】,本人博客http://www.kyson.cn 也在不停的更新中,欢迎一起讨论

iOS系统提供了多种键盘,我们可以通过Enum类型

typedef NS_ENUM(NSInteger, UIKeyboardType) {
    UIKeyboardTypeDefault,
    UIKeyboardTypeASCIICapable, can enter ASCII characters
    UIKeyboardTypeNumbersAndPunctuation,
    UIKeyboardTypeURL,
    UIKeyboardTypeNumberPad,
    UIKeyboardTypePhonePad,
    UIKeyboardTypeNamePhonePad,
    UIKeyboardTypeEmailAddress,
    UIKeyboardTypeDecimalPad ,
    UIKeyboardTypeTwitter ,
    UIKeyboardTypeWebSearch ,
    UIKeyboardTypeASCIICapableNumberPad ,
    UIKeyboardTypeAlphabet = UIKeyboardTypeASCIICapable,
};

设置。但有的时候由于某些特殊业务的需要,我们不得不自定义键盘,比如某些银行的APP处于安全考虑,他们键盘数字的位置是随机的,这个时候只能自定义键盘。幸运的是,iOS也为我们提供了多种方式自定义键盘。我们可以根据自身情况选择合适的方案。

对现有键盘稍加改动

这种情况适合身份证的输入。由于身份证大部分情况下都是数字,偶尔可能出现“X”字符,如果我们弃用数字键盘直接使用诸如UIKeyboardTypeNumbersAndPunctuation等包含数字和字符的键盘又显得没有太大必要,那稍加改动数字键盘是个不错的选择。思路也很简单,在弹出键盘的同时获取键盘对应的window,在window上加上我们需要的按钮即可。如下是笔者改动的数字键盘。

更改现有键盘

下面,我对重点代码做个讲解:

-(void)keyboardWillShow:(NSNotification *)notification{
    //移除掉原先添加的按钮
    [self.extrakeyButton removeFromSuperview];
    self.extrakeyButton     = nil;
    //这几行代码相信看了之前系列博客的读者应该很熟悉了
    NSDictionary *userInfo  = [notification userInfo];
    CGFloat animationDuration   = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
    CGRect kbEndFrame           = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    CGFloat kbHeight            = kbEndFrame.size.height;
    //以下是对添加的X按钮Frame的设置
    CGFloat extrakeyButtonX = 0;
    CGFloat extrakeyButtonW = 0;
    CGFloat extrakeyButtonH = 0;
    extrakeyButtonW = (SCREEN_WIDTH - 7) / 3;
    extrakeyButtonH = kbHeight / 4;
    CGFloat extrakeyButtonY = 0;
    extrakeyButtonY = SCREEN_HEIGHT + kbHeight - extrakeyButtonH;
    //创建“X”按钮,并设置相应的属性
    self.extrakeyButton = [[UIButton alloc] initWithFrame:CGRectMake(extrakeyButtonX, extrakeyButtonY, extrakeyButtonW, extrakeyButtonH)];
    [self.extrakeyButton addTarget:self action:@selector(buttonDidClicked) forControlEvents:UIControlEventTouchUpInside];
    self.extrakeyButton.titleLabel.font = [UIFont systemFontOfSize:27];
    [self.extrakeyButton setTitle:@"X" forState:(UIControlStateNormal)];
    [self.extrakeyButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    //获取键盘对应的Window(这段代码只在iOS 11上做过测试,还不够严谨)
    UIWindow *tempWindow = [[[UIApplication sharedApplication] windows] lastObject];
    [tempWindow addSubview:self.extrakeyButton];
    //设置动画
    [UIView animateWithDuration:animationDuration animations:^{
        CGRect frame    = self.extrakeyButton.frame;
        frame.origin.y  = frame.origin.y - kbHeight;
        self.extrakeyButton.frame = frame;
    } completion:nil];
}

以上代码只在iOS11的iPhone 8 Plus 上做过测试,可能不具备一定的普遍性,比如iPhone X的键盘位置有一定改变,按钮的位置需要加代码兼容。因此这种解决方案非常局限,只能用于身份证等业务非常简单的备选方案。有个iOS开发者对这个键盘做了个封装,读者可以点击这里获取

自己设计一个键盘

iOS中可以通过设置TextField/TextView的inputView来定制键盘,

//The custom input view to display when the text field becomes the first responder.
@property(readwrite, strong) UIView *inputView;
自定义键盘

这个自定义键盘就解决了我们开头提到的问题:键盘上的数字是随机排列的0-9,如果需要添加新的按键可以添加到键盘剩下的空白中。下面来讲解一下核心代码的实现:

CustomKeyboardView *keyView = [[CustomKeyboardView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 176)];
self.xTextField.inputView = keyView;

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = UIColor.lightGrayColor;
        //创建数字数组,并打乱
        NSMutableArray *integers = [[NSMutableArray alloc] init];
        for (NSInteger i = 0; i < 10; ++i) {
            [integers addObject:@(i)];
        }
        NSArray  *shuffledIntegers = [self shuffle:integers];
        //添加数字按钮
        for (NSInteger index = 0; index < 10; ++index) {
            UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
            btn.backgroundColor = UIColor.grayColor ;
            [btn addTarget:self action:@selector(buttonDidClicked:) forControlEvents:UIControlEventTouchUpInside];
            btn.frame = CGRectMake(CGRectGetWidth(self.frame) / 3 * (index % 3 ), 45 *  (index / 3 ) , CGRectGetWidth(self.frame) / 3 - 1, 44);
            NSString *indexString = [NSString stringWithFormat:@"%@",shuffledIntegers[index]];
            [btn setTitle:indexString forState:UIControlStateNormal];
            [self addSubview:btn];
        }
        
    }
    return self;
}

打乱键盘中数字的布局方法很多,一般的洗牌算法就可以实现:

-(NSArray *)shuffle:(NSArray<NSNumber *> *)array
{
    if(array == nil || array.count < 1)
        return nil;
    NSMutableArray *resultArray = [NSMutableArray arrayWithArray:array];
    NSInteger value;
    NSNumber *median;
    
    for(NSInteger index = 0; index < array.count; index ++){
        value = rand() % resultArray.count;
        median = resultArray[index];
        
        resultArray[index] = resultArray[value];
        resultArray[value] = median;
    }
    return resultArray;
}

最后是点击键盘按钮后的回调处理

-(void)buttonDidClicked:(UIButton *) sender{
    if (self.delegate) {
        [self.delegate keyboardItemDidClicked:sender.titleLabel.text];
    }
}

相比较而言,大家是否觉得这种方法比第一种方法既简单又简洁?

本文Demo的代码获取

引用

iOS身份证键盘
iOS自定义键盘demo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,755评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,369评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,799评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,910评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,096评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,159评论 3 411
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,917评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,360评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,673评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,814评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,509评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,156评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,123评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,641评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,728评论 2 351

推荐阅读更多精彩内容