UIKeyboardTypeNumberPad 数字键盘自定义按键

71 篇文章 0 订阅
66 篇文章 0 订阅

需求背景

最近做一个搜索用户的功能,这里使用了UISearchBar。由于搜索的方式只有手机号码,所以这里的键盘要限制为数字输入,可以这么做:

<code class="language-Objective-C hljs avrasm has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.searchBar</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.keyboardType</span> = UIKeyboardTypeNumberPad<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

这里写图片描述

但是这里有个问题,就是数字键盘上面没有“搜索”按钮,这样子用户在输入完手机号码后无法搜索。所以这个时候我们需要自己添加一个自定义的搜索按钮,然后加到键盘上面。

解决思路

  1. 自定义搜索button
  2. 监听键盘出现的事件
  3. 遍历搜索的Windows窗体,找到键盘的窗体,然后遍历其子视图,找到我们真正需要的键盘视图
  4. 把我们自定义的按钮加到上面找到的视图里

这里要注意的一点,随着iOS SDK的不断发展,keyboard的视图名称也不断在更新变化,当你调试以下代码无法得到期待的效果时,请重新遍历一次窗台,然后慢慢调试,找到真正需要的视图名称。

解决代码

1.自定义搜索按钮
<code class="hljs bash has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">// 搜索按钮
    _searchButton = [UIButton buttonWithType:UIButtonTypeCustom];
    _searchButton.frame = CGRectMake(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">163</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">106</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">53</span>);
    [_searchButton <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">set</span>Title:@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"搜索"</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>State:UIControlStateNormal];
    [_searchButton <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">set</span>TitleColor:[UIColor blackColor] <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>State:UIControlStateNormal];
    [_searchButton addTarget:self action:@selector(SearchButtonDidTouch:) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>ControlEvents:UIControlEventTouchUpInside]; </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>
2.监听键盘出现的事件
<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">[[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSNotificationCenter</span> defaultCenter] addObserver:<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span> selector:<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@selector</span>(keyboardWillShowOnDelay:) name:UIKeyboardWillShowNotification object:<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">nil</span>];

- (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)keyboardWillShowOnDelay:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSNotification</span> *)notification {
     [<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span> performSelector:<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@selector</span>(keyboardWillShow:) withObject:<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">nil</span> afterDelay:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>];
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>

这里面监听通知后的执行函数并非立马执行查找窗体的函数,是因为在iOS4后,键盘添加到窗体的事件放到了下一个EventLoop,所以我们采用了延迟的方法。

3. 遍历视图,并添加按钮
<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">- (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)keyboardWillShow:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSNotification</span> *)notification {

    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIView</span> *foundKeyboard = <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">nil</span>;
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIWindow</span> *keyboardWindow = <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">nil</span>;

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIWindow</span> *testWindow in [[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIApplication</span> sharedApplication] windows]) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (![[testWindow class] isEqual:[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIWindow</span> class]]) {
            keyboardWindow = testWindow;
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;
        }
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!keyboardWindow) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (__<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">strong</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIView</span> *possibleKeyboard in [keyboardWindow subviews]) {

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> ([[possibleKeyboard description] hasPrefix:@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"<UIInputSetContainerView"</span>]) {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (__<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">strong</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIView</span> *possibleKeyboard_2 in possibleKeyboard<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.subviews</span>) {
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> ([possibleKeyboard_2<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.description</span> hasPrefix:@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"<UIInputSetHostView"</span>]) {
                    foundKeyboard = possibleKeyboard_2;
                }
            }
        }
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (foundKeyboard) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> ([[foundKeyboard subviews] indexOfObject:_searchButton] == <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSNotFound</span>) {
            [foundKeyboard addSubview:_searchButton];
        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
            [foundKeyboard bringSubviewToFront:_searchButton];
        }
    }
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li></ul>

这里写图片描述

这样子我们就完成了添加自定义按钮的需求了。 
如果什么不正确的地方,欢迎指教。 
本文解决思路主要参考网上许多前辈的解决思路,在此感谢他们的贡献!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值