輕鬆處理最下方 UIButton 被 Keyboard 遮住的問題
按鈕放最下方的設計問題
有時候 App 為了設計上的需求,並不採用官方的右上 Edit/Done 的作法,而是將確定的按鈕放在最下方,我相信大家用 Windows 久了,也習慣看到按鈕在最下方。這個作法乍看下沒什麼問題…
不過在實作上,卻會遇到按鍵昇起之後擋住了按鈕的尷尬情況。 = =”
方法一:使用 UITableViewController 自動處理
如果 UI 是使用 UITableViewController 的話,很幸運的它會自動處理這個問題。這裡有個小技巧,要將 TextView 與 Button 放在同一個 Cell 裡,若放在下一個 Cell 的話還是一樣會被擋住。
降下 keyboard 作法:在 button 的動作裡加上
[self.textView resignFirstResponder];
不適用情形:相對的這個頁面就變成可以捲動了,並不一定會符合設計的需求。
方法二: 使用 UITextField的UITextFieldDelegate Protocol
如果上方的文字輸入區塊只需一行的話,可以使用 UITextField 來處理,而藉由 keyboard 的 textFieldShouldReturn 來處理:
作法如下:
1. 讓 UIViewController 實作 UITextFieldDelegate Protocol
@interface TextFieldViewController ()
2. 將按鍵設為 Done
[self.textField setReturnKeyType:UIReturnKeyDone];
3. 將 textfield.delegate 設為自己
self.textField.delegate = self;
4. 實作 textFieldShouldReturn 來降下 keyboard
- (BOOL)textFieldShouldReturn:(UITextField *)textField { [textField resignFirstResponder]; return YES; }
不適用情形:如果上方的文字輸入區塊是允許換行的,就需使用 UITextView, 而上述的作法就無法進行。
方法三: 使用UITextView與 Auto Layout
其實這裡有個很簡單的作法來處理:在 Keyboard昇起的同時,也將 Button 昇到 keyboard 上方即可。
作法如下:
1. 先設好 AutoLayout constraints
TextView 的離上下左右皆為 20
Button 離左右下方為 30
Button 高度=50
2. 將 Button 離下方的 constraint 拉出來設 IBOutlet
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomHeightConstraint;
3. 在 ViewDidLoad 裡增加 listen keyboard notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillChangeFrameNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
4. 在 keyboard 昇起與降下時,改變 constraint 的值,這樣就可以達成目的了
#pragma mark - keyboard handling - (void)keyboardWillShow:(NSNotification *)notification { NSDictionary *info = [notification userInfo]; NSValue *kbFrame = [info objectForKey:UIKeyboardFrameEndUserInfoKey]; NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; CGRect keyboardFrame = [kbFrame CGRectValue]; CGFloat height = keyboardFrame.size.height; self.bottomHeightConstraint.constant = height+20; [UIView animateWithDuration:animationDuration animations:^{ [self.view layoutIfNeeded]; }]; } - (void)keyboardWillHide:(NSNotification *)notification { NSDictionary *info = [notification userInfo]; NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; self.bottomHeightConstraint.constant = 20; [UIView animateWithDuration:animationDuration animations:^{ [self.view layoutIfNeeded]; }]; }
範例 GitHub : https://github.com/orangedream/TextViewAndKeyboard.git