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方法