iPhone在数字键盘上添加完成按键

在 iPhone 上面開發應用程式時, 在使用輸入鍵盤時, 或多或少都會遇到客制化鍵盤的問題, 這邊筆者以
簡單的數字鍵盤來示範客制化的動作. 這部份我想網路上已經有不少 sample code , 但大部份基本上都是
以 SDK 3.x 的版本去實作, 以"特定寫法"來實作客制化在 iOS4 會有問題, 這部份稍候會提到兩版本的差異.

上述看到的例子是 UIKeyboardTypeNumberPad 搭配 "Done" 的圖示所組合而成的. 在開
始介紹如何實作之前, 先稍微提一下網路上查到的一些範例寫法. 因為 SDK 升版之
後在架構上有做了些修改, 所以導致行為上的不正確. 以下面這例子為例, 它可以正
常的在 iOS4 之前的版本運行, 但在 iOS4 上卻會有看不到上面 "Done" 圖示的問題.

- (void)loadView{
    ...
    textFieldContent.delegate = self;
    textFieldContent.placeholder = @"press me";
    textFieldContent.keyboardType = UIKeyboardTypeNumberPad;
    textFieldContent.returnKeyType = UIReturnKeyDone;
    [self.view addSubview:textFieldContent];
    [textFieldContent release];
    
    [[NSNotificationCenter defaultCenteraddObserver:self 
                                    selector:@selector(keyboardWillShow:) 
                                        name:UIKeyboardWillShowNotification 
                                      object:nil];
    
}

- (void)keyboardWillShowOnDelay:(NSNotification *)notification{
    UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
    doneButton.frame = CGRectMake(016310653);
    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];
    
    UIWindow* tempWindow = [[[UIApplication sharedApplicationwindowsobjectAtIndex:1];
    UIView* keyboard;
    for(int i=0; i<[tempWindow.subviews count]; i++) {
        keyboard = [tempWindow.subviews objectAtIndex:i];
        if([[keyboard descriptionhasPrefix:@"<UIKeyboard"] == YES)
            [keyboard addSubview:doneButton];
    }
}

上述這段代碼主要原理是透過跟 OS 註冊 keyboard 相關的 notification, 並在顯示
keyboard 時, 在 keyboard view 上添加所需要的特定 UIView, 簡單流程大致如下
1. 註冊 UIKeyboardWillShowNotification : 當 keyboard 要秀時, OS 就會呼叫
    keyboardWillShow
2.  當被 keyboardWillShow 叫用時, 搜尋屬於 keyboard 的 view
   if([[keyboard descriptionhasPrefix:@"<UIKeyboard"] == YES)
3. 當找到所需要的 view 時, 再將需要的 view 加入即可
   [keyboard addSubview:doneButton];
上面就是一個 customized keyboard 的簡單實作流程. 但是為什麼這段 code 會無法
在 iOS4 上正確執行呢? 問題點主要出在上述的第 2 個步驟.
在舊的 SDK 中, 當 UIKeyboardWillShowNotification 事件發生且叫用 keyboardWillShow 
時, 此時的 keyboard view 已經被添加到 windows 裡了, 但是在 iOS4 的世界中, 相同
情況發生時, keyboard view 卻會在下個 event loop 裡才會被添加到 windows 中, 也
就是因為如此, 所以上述
[[[UIApplication sharedApplicationwindowsobjectAtIndex:1];
會找不到 keyboard view. 除了這原因以外, 還有另一個重要的差異性, 第 2 步驟所比
對的 @"<UIKeyboard" 字串在 iOS4 中也被修正過, 它被藏在 @"<UIPeripheralHostView"
裡.
針對這兩點, 所以將只要將之修正即可正常的在 iOS4 上執行
1. keyboard view
   既然知道是 keyboard view 會在下個 event loop 才會被放到 windows 裡, 所以我們
   可以透過下面方式將 keyboardWillShow 延遲叫用
   [self performSelector:@selector(keyboardWillShow:) withObject:nil afterDelay:0];
2. 修正比對 @"<UIKeyboard" 的方式

   if ([[possibleKeyboard descriptionhasPrefix:@"<UIPeripheralHostView"]) 
       possibleKeyboard = [[possibleKeyboard subviewsobjectAtIndex:0];

   if ([[possibleKeyboard descriptionhasPrefix:@"<UIKeyboard"])  
   {
       foundKeyboard = possibleKeyboard;
       break;
   }                
經過上述兩個修正之後的 code 大概會如下 :
    [[NSNotificationCenter defaultCenteraddObserver:self 
                    selector:@selector(keyboardWillShowOnDelay:) 
                        name:UIKeyboardWillShowNotification 
                      object:nil];

- (void)keyboardWillShowOnDelay:(NSNotification *)notification
{
    [self performSelector:@selector(keyboardWillShow:) withObject:nilafterDelay:0]; 
}

- (void)keyboardWillShow:(NSNotification *)notification
{    
    UIView *foundKeyboard = nil;
    
    UIWindow *keyboardWindow = nil;
    for (UIWindow *testWindow in [[UIApplication sharedApplicationwindows]) 
    {
        if (![[testWindow classisEqual:[UIWindow class]]) 
        {
            keyboardWindow = testWindow;
            break;
        }
    }
    if (!keyboardWindow) return;
    
    for (UIView *possibleKeyboard in [keyboardWindow subviews]) 
    {            
        //iOS3
        if ([[possibleKeyboard descriptionhasPrefix:@"<UIKeyboard"]) 
        {
            foundKeyboard = possibleKeyboard;
            break;
        }
        else
        {
            // iOS 4 sticks the UIKeyboard inside a UIPeripheralHostView.
            if ([[possibleKeyboard descriptionhasPrefix:@"<UIPeripheralHostView"]) 
            {
                possibleKeyboard = [[possibleKeyboard subviewsobjectAtIndex:0];
            }                                                                                
            
            if ([[possibleKeyboard descriptionhasPrefix:@"<UIKeyboard"]) 
            {
                foundKeyboard = possibleKeyboard;
                break;
            }                
        }            
    }
    
    if (foundKeyboard) 
    {
        // create custom button
        UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
        doneButton.frame = CGRectMake(016310653);
        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];
        
        [foundKeyboard addSubview:doneButton];
    }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值