en

hi, it seems you are using microsoft internet explorer. it doesn't match web standard and causes problems browsing this site. please please please use mozilla firefox or google chrome instead. thank you!

zh

哦哦!您正在使用Internet Explorer 瀏覽器,它與我們的網頁標準並不相容,可能會導致畫面顯示不正常。
請改用 Mozilla Firefox 或者 Google Chrome 才能正常瀏覽本網站,謝謝!

1.20.2012

收起虛擬鍵盤的各種方法


使用虛擬鍵盤來輸入資訊,是 iOS 的重要互動方式之一,虛擬鍵盤通常會自動出現在可以編輯的 UITextField 或是 UITextView 的編輯事件中,叫出鍵盤固然容易,但是要把它收起來,可就沒有這麼簡單,之前在 UITextField 輸入結束後的收起小鍵盤的方式一文中,介紹了如何在編輯完成之後收起虛擬鍵盤,但是如果您的元件並沒有對應的事件可以讓你收起虛擬鍵盤,那又該如何做?下列我們以類似的元件 UITextView 為例,介紹一些通用的方法。


點擊編輯區以外的地方(UIView)
這是一種很直覺的方法,當不再需要使用虛擬鍵盤時,只要點擊虛擬鍵盤和編輯區域外的地方,就可以將鍵盤收起,下面程式碼是在 UIView 中內建的觸碰事件方法函式,您可以參考 Touch Panel / 觸碰螢幕 / 壓力感應器的基本使用方式一文,找到更多關於觸碰事件的方法函式。
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    if (![myTextView isExclusiveTouch]) {
        [myTextView resignFirstResponder];
    }
}

如果要使用此方式請務必記得,你操作畫面的 Custom Class 一定要是 UIView 才行。

畫面的 Custom Class 為 UIView


點擊編輯區域以外的地方(UIControl)
收起虛擬鍵盤的方式與前一種相同,但是如果你的觸碰事件裡已經且寫滿了程式碼,那麼就可以考慮使用,UIControl 的 Touch Up Inside 事件來收起鍵盤,方法是將以下程式碼與 UIControl 的 Touch Up Inside 事件連結即可。
- (IBAction)dismissKeyboard:(id)sender {
    [myTextView resignFirstResponder];
}

如果要使用此方式請務必記得,你操作畫面的 Custom Class 一定要是 UIControl 才行。

畫面的 Custom Class 為 UIControl

將收起鍵盤的方法與 UIControl 事件連結


使用製作收起鍵盤的按鈕
當沒有編輯區域以外的地方可供點擊來收起鍵盤,自己製作一個按鈕來收起目前的虛擬鍵盤,也是一個不錯的方法,由於按鈕必須在虛擬鍵盤出現才能顯示於畫面上,因此必須借用 NSNotificationCenter 來幫助我們判斷目前鍵盤的狀態,您可以在類似 Observer Pattern 的 NSNotificationCenter 一文中,找到更多關於 NSNotificationCenter 的資訊。

首先在 viewDidLoad: 事件中,向 NSNotificationCenter 進行註冊,告訴 NSNotificationCenter 我們的 doneButtonshow: 方法函式,想要訂閱有關 UIKeyboardDidShowNotification 的訊息事件。
- (void)viewDidLoad {
    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector (doneButtonshow:) name: UIKeyboardDidShowNotification object:nil];
}

現在每當虛擬鍵盤出現時,就會自動呼叫我們自定義的 doneButtonshow: 方法函式,接下來只要在該方法函式裡定義按鈕出現的方法即可。
-(void) doneButtonshow: (NSNotification *)notification {
    doneButton = [UIButton buttonWithType: UIButtonTypeRoundedRect];
    doneButton.frame = CGRectMake(0, 228, 70, 35);
    [doneButton setTitle:@"完成編輯" forState: UIControlStateNormal];
    [doneButton addTarget: self action:@selector(hideKeyboard) forControlEvents: UIControlEventTouchUpInside];

    [self.view addSubview:doneButton];
}

最後是實作按鈕按下去時的 hideKeyboard: 方法函式,務必記得要在函式中移除該按鈕。
-(void) hideKeyboard {
    [doneButton removeFromSuperview];
    [myTextView resignFirstResponder];
}

ps:若是不想透過 NSNotificationCenter 的方式來製作收起鍵盤按鈕,也可以考慮採用虛擬鍵盤的 AccessoryView 一文中的方式來製作此按鈕。


使用判斷輸入字元
如果要使用輸入特定字元(例如 return 換行字元)來收起鍵盤,必須先在類別內的 @interface 區段採用 <UITextViewDelegate> 協定,您可以參考 Protocol 協定的使用方式一文,獲得更多關於協定的資訊。


在採用 <UITextViewDelegate> 協定之後,接著實作出協定內的 textView:shouldChangeTextInRange:replacementText:方法函式,此方法函式會在字元輸入時觸發,而回傳的 BOOL 值則代表該字元是否要作用,下列程式碼就是在此方法函式中,使用判斷輸入字元的方式來收起虛擬鍵盤(判斷字元為 return 換行字元)。
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    if ([text isEqualToString:@"\n"]) {
        [myTextView resignFirstResponder];
        return NO;
    }
    return YES;
}

最後別忘記在 viewDidLoad: 事件中,將 UITextView 的代理物件指向自己,這樣程式才能正確找到實作 <UITextViewDelegate> 協定方法函式的類別。
- (void)viewDidLoad
{
    [super viewDidLoad];

    myTextView.delegate = self;
}


關於鍵盤遮蔽的問題
如果您在實作上有遭遇到鍵盤遮蔽編輯區域的問題,可以參考使用 Animation 解決小鍵盤擋住 UITextField 的問題一文,透過 Core Graphic 的 Animation 功能,在鍵盤出現時同時移動編輯區域來解決遮蔽的問題。






沒有留言:

張貼留言