创建分类
头文件
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UITextField (handleKeyboardShelter)
/**
处理键盘遮挡
@param vc 当前textfield所在的VC
*/
- (void)handleKeyboardShelterWithViewController:(UIViewController *)vc;
/**
处理dealloc 要在当前textfield所在的VC中调用该方法
*/
- (void)handleDealloc;
@end
NS_ASSUME_NONNULL_END
.m 文件
#import "UITextField+handleKeyboardShelter.h"
#import <objc/runtime.h>
static NSString *kCurrentVC = @"UITextFieldHandleKeyboardShelterCurrentVC";
static NSString *kCurrentVCFrame = @"UITextFieldHandleKeyboardShelterCurrentVCFrame";
@implementation UITextField (handleKeyboardShelter)
- (void)handleKeyboardShelterWithViewController:(UIViewController *)vc {
[self setCurrentVC:vc];
//监听键盘展示和隐藏的通知
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
- (void)handleDealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)keyboardWillShow:(NSNotification *)notification{
if (![self isFirstResponder]) {
return;
}
UIViewController *vc = [self currentVC];
CGRect rect = [self.superview convertRect:self.frame toView:vc.view];//获取相对于self.view的位置
NSDictionary *userInfo = [notification userInfo];
NSValue* aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];//获取弹出键盘的fame的value值
CGRect keyboardRect = [aValue CGRectValue];
keyboardRect = [vc.view convertRect:keyboardRect fromView:vc.view.window];//获取键盘相对于self.view的frame ,传window和传nil是一样的
CGFloat keyboardTop = keyboardRect.origin.y;
NSNumber * animationDurationValue = [userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];//获取键盘弹出动画时间值
NSTimeInterval animationDuration = [animationDurationValue doubleValue];
if (keyboardTop < CGRectGetMaxY(rect)) {//如果键盘盖住了输入框
CGFloat gap = keyboardTop - CGRectGetMaxY(rect) - 10;//计算需要网上移动的偏移量(输入框底部离键盘顶部为10的间距)
__weak typeof(vc)weakSelf = vc;
CGRect viewFrame = vc.view.frame;
[self setCurrentVCFrame:viewFrame];
viewFrame.origin.y = gap + viewFrame.origin.y;
[UIView animateWithDuration:animationDuration animations:^{
weakSelf.view.frame = viewFrame;
}];
}
}
- (void)keyboardWillHide:(NSNotification *)notification{
if (![self isFirstResponder]) {
return;
}
UIViewController *vc = [self currentVC];
NSDictionary *userInfo = [notification userInfo];
NSNumber * animationDurationValue = [userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];//获取键盘隐藏动画时间值
NSTimeInterval animationDuration = [animationDurationValue doubleValue];
if (vc.view.frame.origin.y < 0) {//如果有偏移,当影藏键盘的时候就复原
CGRect frame = [self currentVCFrame];
__weak typeof(vc)weakSelf = vc;
[UIView animateWithDuration:animationDuration animations:^{
weakSelf.view.frame = frame;
}];
}
}
- (UIViewController *)currentVC {
return objc_getAssociatedObject(self, &kCurrentVC);
}
- (void)setCurrentVC:(UIViewController *)vc {
return objc_setAssociatedObject(self, &kCurrentVC, vc, OBJC_ASSOCIATION_ASSIGN);
}
- (CGRect)currentVCFrame {
NSString *frameStr = objc_getAssociatedObject(self, &kCurrentVCFrame);
return CGRectFromString(frameStr);
}
- (void)setCurrentVCFrame:(CGRect)frame {
NSString *frameStr = NSStringFromCGRect(frame);
return objc_setAssociatedObject(self, &kCurrentVCFrame, frameStr, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
@end
使用方法:
1.在textField所在控制器的ViewDidLoad方法添加[self.phoneNumberTextField handleKeyboardShelterWithViewController:self];
- (void)viewDidLoad {
[super viewDidLoad];
//..........
[self.phoneNumberTextField handleKeyboardShelterWithViewController:self];
}
2.在textField所在控制器的dealloc方法中释放
- (void)dealloc {
[self.phoneNumberTextField handleDealloc];
}
两行代码搞定.