iOS 處理鍵盤遮擋TextField、TextView問題


  之前處理鍵盤遮擋問題都是在每一個控制器進行單獨處理,這樣做真的是非常的費事,今天在做項目的時候就想到自己封裝一個,記錄一下這個“跌宕起伏”的過程。

  思路是這樣的:計算文本編輯控件Frame與鍵盤Frame,如果遮擋則移動控制器View。

  創建控制器類:WKAvoidKeyboardViewController

  

 1 #import <UIKit/UIKit.h>
 2 
 3 @interface WKAvoidKeyboardViewController : UIViewController
 4 
 5 @property (nonatomic, strong) UITextField *editTextField;
 6 @property (nonatomic, strong) UITextView *editTextView;
 7 
 8 - (void)hideKeyboard:(NSNotification *)noti;
 9 - (void)showKeyboard:(NSNotification *)noti;
10 
11 
12 @end
13 
14 
15 #import "WKAvoidKeyboardViewController.h"
16 
17 #define GetOSVersion [[UIDevice currentDevice].systemVersion floatValue]
18 
19 #define GetTransformDistance(Distance) (GetOSVersion < 7.1 ? Distance / 2 : Distance)
20 
21 @interface WKAvoidKeyboardViewController ()<UITextFieldDelegate, UITextViewDelegate>
22 
23 @end
24 
25 @implementation WKAvoidKeyboardViewController
26 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
27 {
28     [self.view endEditing:YES];
29 }
30 @end

 

  步驟1:通過通知獲取當前編輯的文本控件

//注冊通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(showKeyboard:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(hideKeyboard:) name:UIKeyboardWillHideNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldBeginEditing:) name:UITextFieldTextDidBeginEditingNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldBeginEditing:) name:UITextViewTextDidBeginEditingNotification object:nil];
- (void)textFieldBeginEditing:(NSNotification *)noti
{
    self.editTextField = noti.object;
    self.editTextView = nil; 
}
- (void)textViewBeginEditing:(NSNotification *)noti
{
    self.editTextView = noti.object;
    self.editTextField = nil;
}

 

  步驟2:通知獲取鍵盤高度

  步驟3:計算是否需要移動

  

#pragma mark - 鍵盤躲避

- (void)showKeyboard:(NSNotification *)noti
{
    self.view.transform = CGAffineTransformIdentity;
    UIView *editView = _editTextView ? _editTextView : _editTextField;
    
    CGRect tfRect = [editView.superview convertRect:editView.frame toView:self.view];
    NSValue *value = noti.userInfo[@"UIKeyboardFrameEndUserInfoKey"];
    NSLog(@"%@", value);
    CGRect keyBoardF = [value CGRectValue];
    
    CGFloat animationTime = [noti.userInfo[@"UIKeyboardAnimationDurationUserInfoKey"] floatValue];
    CGFloat _editMaxY = CGRectGetMaxY(tfRect);
    CGFloat _keyBoardMinY = CGRectGetMinY(keyBoardF);
    NSLog(@"%f %f", _editMaxY, _keyBoardMinY);
    if (_keyBoardMinY < _editMaxY) {
        CGFloat moveDistance = _editMaxY - _keyBoardMinY;
        [UIView animateWithDuration:animationTime animations:^{
            self.view.transform = CGAffineTransformTranslate(self.view.transform, 0, -moveDistance);
        }];
        
    }
}

- (void)hideKeyboard:(NSNotification *)noti
{
    //    NSLog(@"%@", noti);
    self.view.transform = CGAffineTransformIdentity;
}

  初步試驗:UITextFiled成功,然后到了UITextView,坑爹的問題粗線了=.=, UITextViewTextDidBeginEditingNotification 發送時間是在鍵盤彈出通知之后的,導致第一次點擊TextView沒有用,點擊第二次才能產生效果。於是乎,我又開始嘗試用TextView的Delegate來做,想當然的使用的代理方法

- (void)textViewDidBeginEditing:(UITextView *)textView

1 - (void)textViewDidBeginEditing:(UITextView *)textView
2 {
3     
4 }

  令人失望的是textViewDidBeginEditing:方法調用依然是在鍵盤通知彈出后再調用,此時心中想的是:嗶了狗了,讓人怎么玩!還是看看其他方法吧。於是在代理方法中看到了

- (BOOL)textViewShouldBeginEditing:(UITextView *)textView

  嘗試之后,此方法的確在鍵盤彈出前調用,大功告成,接下來就是設置代理的問題了

  設置代理方法如下:

 1 - (void)searchTextViewWithView:(UIView *)view
 2 {
 3     for (UIView *subview in view.subviews)
 4     {
 5         if ([subview isKindOfClass:[UITextView class]]) {
 6             ((UITextView *)subview).delegate = self;
 7         }
 8         if ([subview isKindOfClass:[UITextField class]]) {
 9             ((UITextField *)subview).delegate = self;
10         }
11         [self searchTextViewWithView:subview];
12     }
13 }

  至此大功告成,使用方法:繼承WKAvoidKeyboardViewController,如果是用故事版創建的文本控件,啥都不用做,如果是用代碼創建的,則需要在ViewDidLoad中調用searchTextViewWithView方法

  完整代碼下載地址:https://github.com/WuKongCoo1/AvoidKeyboardDemo.git

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM