iPhone 在ios4.0及以前键盘上添加自定义键盘

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

iPhone 在ios4.0及以前键盘上添加自定义键盘 - 勇者之尊 - 勇者之尊

上述看到的例子是  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   defaultCenter addObserver : self  
                                     selector : @selector ( keyboardWillShow :) 
                                         name : UIKeyboardWillShowNotification  
                                       object : nil ];
    
}

- ( void )keyboardWillShowOnDelay:( NSNotification  *)notification{
     UIButton  *doneButton = [ UIButton   buttonWithType : 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 ];
    
     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 : @"<UIKeyboard" ] ==  YES )
            [keyboard  addSubview :doneButton];
    }
}

上述這段代碼主要原理是透過跟 OS 註冊 keyboard 相關的 notification, 並在顯示
keyboard 時, 在 keyboard view 上添加所需要的特定 UIView, 簡單流程大致如下
1. 註冊  UIKeyboardWillShowNotification  : 當 keyboard 要秀時, OS 就會呼叫
     keyboardWillShow
2.  當被  keyboardWillShow  叫用時, 搜尋屬於 keyboard 的 view
    if ([[keyboard  description hasPrefix : @"<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   sharedApplication windows objectAtIndex : 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  defaultCenter addObserver : self  
                     selector: @selector( keyboardWillShowOnDelay:) 
                         name: UIKeyboardWillShowNotification 
                       object: nil];

- ( void)keyboardWillShowOnDelay:( NSNotification *)notification
{
    [ self  performSelector : @selector ( keyboardWillShow :) withObject : nil afterDelay : 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];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值