iOS自定义数字键盘适配

来自产品经理的"简单"需求一则

需求:在输入身份证号码的时候,弹出来的键盘是能够切换到字母的九宫格数字键盘。(左边原生系统,右边需求)

步骤一:添加键盘监控

       系统提供了notification监听键盘的出现和消失。Notification不仅可以监听键盘的状态变化,还携带一些其它信息,键盘的位置,大小信息,动画类型等。

步骤二:处理监听事件

在回调函数我们首先需要找到的是当前键盘所在在window

[[UIApplication sharedApplication] windows]能够获取当前界面windows的数组。

    系统键盘是在一个系统新建的级别最高的UIWindow上,我们只需要找到这个UIWindow 就可以,在这个window 上添加button,因此我们要的keyboard所在的UIWindow的名称是UITextEffectsWindow。找到我们所需要的window之后,直接添加我们的button。在调试的过程中发现,当前设置只在iOS9以下的系统起作用,在iOS9系统中添加的button会被keyboard所在的window覆盖掉。这是为什么呢,再打印当前的windows发现,当前的界面windows的结构已经与之前不一样了。

      对比结构发现在iOS9的系统中多了一个UIRemoteKeyboardWindow,也就是现在最高级别的UIWindow是UIRemoteKeyboardWindow。因此keyboard所在的UIWindow也由之前的UITextEffectsWindow转变为UIRemoteKeyboardWindow。

步骤三:处理第三方键盘

      除了要适配iOS9的系统的情况下,还存在另外一个问题。苹果在iOS8及以上的系统支持第三方输入法(搜狗输入法),现在很多人都下载使用了第三方的输入法 ,会出现什么问题。

     自定义的控件出现在不该出现的位置,这个不是直接设置button的hidden属性为YES呢,不就解决问题了?所以关键问题如何判断当前输入法是否带有第三方扩展输入法?解决的办法有几种:

禁用第三方输入法

无论有没有使用第三方输入法,在APP中有关键盘的场景都禁用。一了百了,简单粗暴。

查找第三方输入法

      第一种方法有点不太友好。我们需要的是有第三方输入法符合要求就使用第三方,没有的就用采用自定义的。 如何判断当前用户是否使用了第三方输入法,如果使用了第三方输入法 就设置button的hidden属性为YES。UITextInputMode:能够得到当前系统的所有输入法。[UITextInputModeactiveInputModes]得到其中的一个NSArray的数组。对比下在有第三方输入法和没有情况下数组的成员:




      通过对比发现在有使用第三方输入法扩展的时候就多了一个UIKeyboardExtensionInputMode,通过这个mode来判断是否使用了输入法扩展。这个mode包含的第三方输入法的其它信息,版本号,或者通过keyValue来读取输入法名称。


当然我们只需要判断当前是否有引进第三方输入法。如果有需要也可以通过条件过滤获取当前第三方输入法。

私有API

也有通过私有APP来获取第三方输入法的信息,但是现在苹果对使用私有API审核很严格,还是不建议了。


2016.7.11 更新

    项目上线之后,有用户反馈贴上的“ABC”这个按钮不会出现。随机概率事件,不是必先的bug无法找到路径,再review了代码之后并没有找到解决方法。猜测是iOS系统在绘制键盘的时候会将这个"ABC"按钮覆盖了。然而你并不能告诉产品经理说,bug无法解决。她会告诉你是bug就肯定能找到解决方法的。你只能绞尽脑汁寻找解决办法的。最终在平衡利弊之后采用的解决方案是用其他方式来替换当前"黏贴"方法。这里就需要提及UITextField的两个属性成员变量:inputView 和 inputAccessoryView,怎么理解这两个成员变量呢?

      从上面那张图,我们可以将键盘看成有两部分组成(当然,键盘还会有其他的部分组成),一个下面键盘部署,一个内容框。相对应的属性就是上半部分是inputView,下半部分是inputAccessoryView。

    我们调用的系统默认键盘的时候,我们看到的键盘view部分就是这个inputView + inputAccessoryView组成。所以如果设置 textField.inputView = nil ,点击textField是不会弹出键盘的,因为这个时候inputView = nil。所以可以通过设置inputView和inputAccessoryView来自定义我们所需要显示的视图。

自定义键盘

自定义键盘就是键盘全部由客户端代码生成,工作量巨大,下面是招行APP的例子:

UIView * keyboardView = /**/

textField.inputView =keyboardView;//输入我们自定义的键盘

textField.inputAccessoryView = nil;


系统键盘+自定义

第一种方法能很好的解决问题,但是这个实现成本有点大,选择一个较为轻量的方法:数字键盘还是使用系统的空间,不改变textField.inputView ,通过设置inputAccessoryView在键盘的顶部添加我们想要的视图。

UIView * keyboardView = /**/

textField.inputAccessoryView =keyboardView;

      这个inputAccessoryView是和键盘一起出现的,不会再出现用户切换不了输入法的问题。如果用户有安装第三方键盘,这个inputAccessoryView也是会出现在键盘顶部。这个时候要注意隐藏。

      有时候会发现设置了inputAccessoryView = nil并没有起作用,因为设置的时机不对,除了在textFieldShouldBeginEditing函数中设置以外,如果要确保为nil的话,可以用方法[textField reloadInputViews] ,该方法会重新绘制一遍键盘,inputAccessoryView 就为空了。

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

推荐阅读更多精彩内容