对iOS系统键盘的hack以及注意事项

本文详细介绍了在iOS应用中对系统自带键盘进行hack的方法,包括如何在键盘弹出时找到并覆盖原有的按钮,以及如何适配横屏情况。同时提供了hack系统键盘的完整流程和关键代码片段,帮助开发者解决在不同需求场景下遇到的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文转载自:http://hikui.is-programmer.com/posts/35019.html


感谢博主的分享。


对iOS系统键盘的hack以及注意事项

在做东方财富通新版的时候,需求组给出的新的需求是,数字键盘使用我们自己做的,而字母键盘使用系统自带的键盘,然而这里出现的一个问题就是,系统键盘进行输入法切换的时候是没有办法切换到自带的键盘中去的。这时候就需要对系统自带键盘进行hack。

原理很简单,就是在系统键盘弹出来时找到系统键盘所在的UIView,然后贴上自己的按钮覆盖掉原先的按钮。难点在于如何找到系统键盘所在的View。

效果图:

从效果图上可见,原先系统键盘的123和地球的图标被替换成了自定义的按钮。

做法:首先在当前的ViewController中监听:UIKeyboardDidShowNotification

 

?
1
[[ NSNotificationCenter defaultCenter]addObserver: self selector: @selector (keyboardDidShow:) name:UIKeyboardDidShowNotification object: nil ];

 

然后自己实现keyboardDidShow方法,在里面根据需要调用下面hackSystemKeyboard方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
- ( void )hackSystemKeyboard
{
     UIView *foundKeyboard = [ self getSystemKeyboard];
     if (foundKeyboard) {
         //如果有原先存在的hack button,删之
         [ self clearKeyboardHack];
         //hackButton 为123button
         //新建hackButton,根据orentation定义不同的frame
         UIButton *hackButton = [UIButton buttonWithType:UIButtonTypeCustom];
         hackButton.backgroundColor = [UIColor clearColor];
         hackButton.tag = 19100;
         if ( self .isLandscape) {
             hackButton.frame = CGRectMake(3, 124, 90, 38);
             UIImage *btnBG = [UIImage imageNamed:@ "hackButtonLandscape.png" ];
             [hackButton setBackgroundImage:btnBG forState:UIControlStateNormal];
         } else {
             hackButton.frame = CGRectMake(2, 173, 77, 43);
             UIImage *btnBG = [UIImage imageNamed:@ "hackButton.png" ];
             [hackButton setBackgroundImage:btnBG forState:UIControlStateNormal];
         }
         [hackButton setShowsTouchWhenHighlighted: YES ];
         [hackButton addTarget: self action: @selector (switchToNumberPad:) forControlEvents:UIControlEventTouchUpInside];
         [foundKeyboard addSubview:hackButton];
     }
}

这里要注意的是,如果这个ViewController支持横屏,则需要准备两套button图片。并且在willAnimateRotationToInterfaceOrientation中需要调用hackSystemButton这个方法。

里面比较重要的是getSystemKeyboard方法:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
- (UIView *)getSystemKeyboard
{
     UIView *foundKeyboard = nil ;
     
     UIWindow *keyboardWindow = nil ;
     for (UIWindow *testWindow in [[UIApplication sharedApplication] windows])
     {
         if (![[testWindow class ] isEqual:[UIWindow class ]])
         {
             keyboardWindow = testWindow;
             break ;
         }
     }
     if (!keyboardWindow)
         return nil ;
     
     for (UIView *possibleKeyboard in [keyboardWindow subviews])
     {
         //iOS3
         if ([[possibleKeyboard description] hasPrefix:@ "<UIKeyboard" ])
         {
             foundKeyboard = possibleKeyboard;
             break ;
         }
         else
         {
             // iOS 4 sticks the UIKeyboard inside a UIPeripheralHostView.
             if ([[possibleKeyboard description] hasPrefix:@ "<UIPeripheralHostView" ])
             {
                 possibleKeyboard = [[possibleKeyboard subviews] objectAtIndex:0];
             }
             
             if ([[possibleKeyboard description] hasPrefix:@ "<UIKeyboard" ])
             {
                 foundKeyboard = possibleKeyboard;
                 break ;
             }
         }
     }
     return foundKeyboard;
}

这里利用了iOS系统组件的Description进行View的判断,iOS 4以后的版本和之前的版本不一样,新版本中把UIKeyboard放在UIPeripheralHostView中。

最后需要注意的是,一个系统键盘在一个应用程序里面是共享的,所以如果这个ViewController中对键盘进行了hack,而在另外一个ViewController中不需要hack,那么需要在本ViewController退出的时候把Hack清理掉。但是在ViewWillDisappear中,我发现getSystemKeyboard方法寻找到的View并不是真正的keyboard,我的一个变通的办法就是在所有会导致ViewWillDisappear的步骤中插入clearKeyboardHack方法。

101年10月17日更新:

清理hack的时机应该是键盘将要隐藏前。只要在NotificationCenter中注册名为UIKeyboardWillHideNotification,收到notification的时候进行一次清理即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值