现在的位置: 首页 > 综合 > 正文

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

2017年11月14日 ⁄ 综合 ⁄ 共 4882字 ⁄ 字号 评论关闭

在 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];
    }
}


抱歉!评论已关闭.