有个朋友问我,微信在聊天窗口有输入文字的时候,返回到聊天列表页,再次进入这个带草稿的聊天页面,键盘是升起来的,且输入框已经在键盘上面(没升起动画)。各位自己可以用微信试试。
监听键盘高度改变的事件,大家都很熟悉,就是下面几个。
UIKIT_EXTERN NSNotificationName const UIKeyboardWillShowNotification __TVOS_PROHIBITED;
UIKIT_EXTERN NSNotificationName const UIKeyboardDidShowNotification __TVOS_PROHIBITED;
UIKIT_EXTERN NSNotificationName const UIKeyboardWillHideNotification __TVOS_PROHIBITED;
UIKIT_EXTERN NSNotificationName const UIKeyboardDidHideNotification __TVOS_PROHIBITED;
监听这几个通知,我们就可以在键盘升起和下架的时候,把输入框始终跟随键盘的顶部运动。
回到我们的问题,我想实现的是push的时候,键盘已经升起,且输入框在键盘上面,二者都没有升起的动画。
但是如果直接跟随键盘高度去改变输入框位置,你会发现在push聊天界面的时候,键盘倒是直接出现了,但这个输入框会有个从开始位置移动到键盘顶部的动画。那么就猜测,微信应该是一开始就将输入框的位置设置在了键盘的顶部,然后再弹窗键盘。要实现这个的话,应该要保存上一次键盘的高度才行。因为你可以发现在viewWillAppear的时候,键盘高度还是0的。
当然可以做个验证,先进入到微信,然后切换到A输入法,输入一些草稿文字之后,退出聊天窗口。然后切换到短信,切换到另外一个键盘高度不一样的输入法B,然后在切换回微信,进入刚刚的聊天界面,可以发现,输入框是有个从A输入法的高度切换到B输入法高度的动画的,时间很短,留意观察。这样就验证了我们的猜测。
故要实现我朋友的这个需求,那么只需要记录一下上一次键盘的高度就行了。
简单的demo如下,push出下面这个vc就可以测试了。
#import "VC2.h"
@interface VC2 ()
@property (strong, nonatomic) UITextField *textField;
@end
static CGFloat sKeyBoardHeight;
static NSString *sText;
@implementation VC2
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
_textField = [UITextField new];
_textField.text = sText;
_textField.placeholder = @"我是输入框";
_textField.layer.borderColor = [UIColor grayColor].CGColor;
_textField.layer.borderWidth = 1;
[self.view addSubview:_textField];
if (sKeyBoardHeight > 0 && sText.length > 0) {
[self.textField becomeFirstResponder];
_textField.frame = CGRectMake(50, self.view.frame.size.height - sKeyBoardHeight - 100, 200, 100);
} else {
_textField.frame = CGRectMake(50, self.view.frame.size.height - 100, 200, 100);
}
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(backgroundTap)];
[self.view addGestureRecognizer:recognizer];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)viewDidDisappear:(BOOL)animated {
sText = self.textField.text;
}
- (void)keyboardWillShow:(NSNotification *)notification {
NSValue *value = [[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey];
CGSize keyboardSize = [value CGRectValue].size;
CGFloat keyboradHeight = keyboardSize.height;
_textField.frame = CGRectMake(50, self.view.frame.size.height - keyboradHeight - 100, 200, 100);
NSLog(@"zzz keyboardWillShow %f", keyboradHeight);
sKeyBoardHeight = keyboradHeight;
}
- (void)keyboardWillHide:(NSNotification *)notification {
_textField.frame = CGRectMake(50, self.view.frame.size.height - 100, 200, 100);
}
- (void)backgroundTap {
[_textField resignFirstResponder];
}
@end