1. 概述
本文要實現(xiàn)的是在iOS上點擊輸入框后盒粮,如果輸入框在鍵盤之下堰酿,那么將自動移動界面使得輸入框在鍵盤之上!就像Android的效果那樣载萌。效果圖如下:
2. 一分鐘實現(xiàn)該效果:
- 點擊這里下載
WPAutoSpringTextViewController.h
,WPAutoSpringTextViewController.m
,UIResponder+FirstResponder.h
,UIResponder+FirstResponder.m
四個文件到你的工程中 - 修改你的ViewController的父類為WPAutoSpringTextViewController
大功告成搪哪,是不是很簡單!如果想了解實現(xiàn)方法摊崭,請繼續(xù)閱讀讼油。
3. 實現(xiàn)原理
首先,我們需要監(jiān)聽鍵盤的廣播:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(wpKeyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(wpKeyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
鍵盤彈出廣播中我們需要獲取鍵盤彈出的高度呢簸,鍵盤彈出的時間矮台。
float duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];
CGFloat keyboardHeight = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
然后我們判斷此時view需要移動的距離,這里首先獲取firstResponder根时,然后判斷其是否為UITextView或UITextField類或其子類瘦赫,再根據(jù)該輸入框在屏幕上的位置計算是否需要彈起view,需要則返回需要彈起的高度蛤迎,不需要則為0确虱。
- (CGFloat)shouldScrollWithKeyboardHeight:(CGFloat)keyboardHeight{
id responder = [UIResponder currentFirstResponder];
if([responder isKindOfClass:[UITextView class]] || [responder isKindOfClass:[UITextField class]]){
UIView *view = responder;
CGFloat y = [responder convertPoint:CGPointZero toView:[UIApplication sharedApplication].keyWindow].y;
CGFloat bottom = y + view.frame.size.height;
if(bottom > SCREEN_HEIGHT - keyboardHeight){
return bottom - (SCREEN_HEIGHT - keyboardHeight);
}
}
return 0;
}
最后當我們發(fā)現(xiàn)需要彈起頁面時則動畫彈起頁面:
CGFloat shouldScrollHeight = [self shouldScrollWithKeyboardHeight:keyboardHeight];
if(shouldScrollHeight == 0){
return;
}
__weak WPAutoSpringTextViewController *weakSelf = self;
[UIView animateWithDuration:duration animations:^{
CGRect bounds = weakSelf.view.bounds;
weakSelf.view.bounds = CGRectMake(0, shouldScrollHeight + 10, bounds.size.width, bounds.size.height);
}];
這里主要的邏輯都已經(jīng)完成了,點擊在鍵盤覆蓋范圍內的輸入框時替裆,界面可以自動彈起校辩。當點擊空白區(qū)域時,鍵盤自動收起扎唾,這個功能代碼如下:
self.view.userInteractionEnabled = YES;
[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(viewClicked)]];
- (void)viewClicked{
if(keyboardIsShowing){
id responder = [UIResponder currentFirstResponder];
if([responder isKindOfClass:[UITextView class]] || [responder isKindOfClass:[UITextField class]]){
UIView *view = responder;
[view resignFirstResponder];
}
}
}
好了大功告成召川! 完整的代碼如下。Github地址
https://github.com/MRsummer/WPAutoSpringKeyboard
#import "WPAutoSpringTextViewController.h"
#import "UIResponder+FirstResponder.h"
#define SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height
@implementation WPAutoSpringTextViewController{
BOOL keyboardIsShowing;
}
-(void)viewDidLoad{
[super viewDidLoad];
[self enableEditTextScroll];
self.view.userInteractionEnabled = YES;
[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(viewClicked)]];
}
- (void)viewClicked{
if(keyboardIsShowing){
id responder = [UIResponder currentFirstResponder];
if([responder isKindOfClass:[UITextView class]] || [responder isKindOfClass:[UITextField class]]){
UIView *view = responder;
[view resignFirstResponder];
}
}
}
- (CGFloat)shouldScrollWithKeyboardHeight:(CGFloat)keyboardHeight{
id responder = [UIResponder currentFirstResponder];
if([responder isKindOfClass:[UITextView class]] || [responder isKindOfClass:[UITextField class]]){
UIView *view = responder;
CGFloat y = [responder convertPoint:CGPointZero toView:[UIApplication sharedApplication].keyWindow].y;
CGFloat bottom = y + view.frame.size.height;
NSLog(@"shouldScrollWithKeyboardHeight -->keyboradHeight %@, keyboradBottom %@, viewY %@, bottom %@", @(keyboardHeight), @(SCREEN_HEIGHT - keyboardHeight), @(y), @(bottom));
if(bottom > SCREEN_HEIGHT - keyboardHeight){
return bottom - (SCREEN_HEIGHT - keyboardHeight);
}
}
return 0;
}
- (void)enableEditTextScroll{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(wpKeyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(wpKeyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(wpKeyboardDidShow) name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(wpKeyboardDidHide) name:UIKeyboardDidHideNotification object:nil];
}
- (void)wpKeyboardDidShow{
keyboardIsShowing = YES;
}
- (void)wpKeyboardDidHide{
keyboardIsShowing = NO;
}
- (void)wpKeyboardWillHide:(NSNotification *)note {
float duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];
__weak WPAutoSpringTextViewController *weakSelf = self;
[UIView animateWithDuration:duration animations:^{
CGRect bounds = weakSelf.view.bounds;
weakSelf.view.bounds = CGRectMake(0, 0, bounds.size.width, bounds.size.height);
}];
}
- (void)wpKeyboardWillShow:(NSNotification *)note {
float duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];
CGFloat keyboardHeight = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
CGFloat shouldScrollHeight = [self shouldScrollWithKeyboardHeight:keyboardHeight];
if(shouldScrollHeight == 0){
return;
}
__weak WPAutoSpringTextViewController *weakSelf = self;
[UIView animateWithDuration:duration animations:^{
CGRect bounds = weakSelf.view.bounds;
weakSelf.view.bounds = CGRectMake(0, shouldScrollHeight + 10, bounds.size.width, bounds.size.height);
}];
}
@end