宝塔服务器面板,一键全能部署及管理,送你10850元礼包,点我领取

原文:http://www.neoos.ch/blog/37-uikeyboardtypenumberpad-and-the-missing-return-key

Luzian Scherrer on 21April 2009.

 

如果你的iPhone app中需要输入数字,你肯定知道使用UIKeyboardTypeNumberPad。如果用过iPhone的键盘,你肯定知道它有一个缺点:UIKeyboardTypeNumberPad没有return键。

 

UPDATE 17 June 2010

随着新iOS(iPad 3.2和iPhone/iPod touch)的到来,正如部分读者在评论中所说,由于苹果修改了SDK,我们的解决方法不能正常工作。现在我们做了一些修改以便在iOS3.13之后正常工作(3.2和4.0GM)。请从文章底部下载完整的Xcode工程。

 

简单说,3.13之后键盘行为发生了改变,在它弹出之前不可能添加按钮在上面。因此done按钮必须在键盘出现之后添加。这点已经过我们的一位读者指出:

explained in more detail.

另外,新的解决方法并不完美。当然,大部分用户不关心这一点。我们会继续寻找更好的解决方案。

事实上,其他几种键盘(除了UIKeyboardTypePhonePad外)都可以用设置returnKey属性的方式释放键盘。因此如何在NumberPad键盘中达到同样的效果?我们找到了一种方法。

查看NumberPad键盘,你可能注意到在它的左边有一个没用的空按钮。那就是我们将加入“return”键的地方。

做法很简单:截下屏幕,将整个空白键切出来,用photoshop水平翻转,擦除它的backspace字样,然后用任何文字比如“return”字样替换它,这里我们采用“Done”这个单词。现在我们有一张图片用于作为按钮的UIControlStateNormal图片。重复整个过程(使用按键被按下时的屏幕截图)以获得第2张图片并用作按钮的UIControlStateHighlighted图片。如下图所示:

现在开始编码。首先,我们需要知道数字键盘什么时候出现,这样我们才好添加我们的定制按钮。幸好,有这么一个通知,正好用于这个目的。首先我们来注册这个通知:

  [[NSNotificationCenter defaultCenter] addObserver:self                                          selector:@selector(keyboardWillShow:)                                              name:UIKeyboardWillShowNotification                                            object:nil];  

别忘了在干完所有事情后,最终你需要从通知中心移除注册过的观察者: 

[[NSNotificationCenter defaultCenter] removeObserver:self];  

接下来是重点。我们必须在keyboardWillShow方法中找出键盘视图并添加一个按钮在上面。键盘视图是我们的application对象的第2个UIWindow中的一个View。因此我们取到这个window(绝大部分情况下它会是第2个window,因此我们使用objectAtIndex:方法就好了),遍历它的view层次结构,一直到我们找到键盘并添加一个按钮在左下角:

– (void)keyboardWillShow:(NSNotification *)note{

// 创建“Done”按钮    

UIButton *doneButton = [UIButtonbuttonWithType:UIButtonTypeCustom];     doneButton.frame =CGRectMake(0,163, 106,53);    doneButton.adjustsImageWhenHighlighted =NO;    

[doneButton setImage:[UIImage imageNamed:@”DoneUp.png”]forState:UIControlStateNormal];    

[doneButton setImage:[UIImage imageNamed:@”DoneDown.png”]forState:UIControlStateHighlighted];    

[doneButton addTarget:self action:@selector(doneButton:) forControlEvents:UIControlEventTouchUpInside];      

// 找到键盘view    

UIWindow* tempWindow = [[[UIApplicationsharedApplication] windows] objectAtIndex:1];    

UIView* keyboard;    

for(int i=0; i<[tempWindow.subviewscount]; i++){

         keyboard = [tempWindow.subviewsobjectAtIndex:i];

         // 找到键盘view并加入“Done”按钮

         if([[keyboarddescription] hasPrefix:@”UIKeyboard”] == YES)

            [keyboard addSubview:doneButton];    

}

}  

就这么简单。空白按钮位于座标(0, 163),大小为 (106, 53).

doneButton 方法的定义对你来说当然不是什么问题。只需要调用text field的resignFirstResponder方法键盘就会解散。

我们仅仅发现当前的iOS3.0 beta版中键盘的图形设计做了轻微改变。这意味着我们需要为适用新样式的而改变定制按钮的位置和图片。

完整的Xcode工程下载:downloadedas an Xcode project

更新3.0兼容: download 3.0compatible Xcode project.
2010最新更新: download the newestversion (适用2.0 – 4.0所有版本)

译者注:

如果iOS版本在3.2以后应使用UIKeyboardDidShowNotification通知,而不是UIKeyboardWillShowNotification。

if ([[[UIDevice currentDevice] systemVersion]floatValue] >= 3.2) {

[[NSNotificationCenter defaultCenter]addObserver:self

 selector:@selector(addButtonToKeyboard)

 name:UIKeyboardDidShowNotification

  object:nil];

} else {

[[NSNotificationCenter defaultCenter]addObserver:self

 selector:@selector(addButtonToKeyboard)

 name:UIKeyboardWillShowNotification

  object:nil];

}

对于ViewController是用IB构建的,应在ViewDidLoad方法而不是loadView方法中注册观察者.

ios5需要改进如下代码:

 

UIWindow* tempWindow = [[[UIApplication sharedApplication] windows]objectAtIndex:1];
UIView* keyboard;
for(int i=0; i<[tempWindow.subviews count]; i++) {
keyboard = [tempWindow.subviews objectAtIndex:i];

if(([[keyboard description]hasPrefix:@”<UIPeripheralHostView”] == YES)||[[keyboard description]hasPrefix:@”<UIKeyboard”] == YES){
CGRect frame = CGRectMake(0.0f, 162.0f, 106.0f, 53.0f);
if ((orientation == UIInterfaceOrientationLandscapeLeft) || (orientation ==UIInterfaceOrientationLandscapeRight)){
frame = CGRectMake(0.0f, 116.0f, 162.0f, 53.0f);