这个库的下载地址:https://github.com/hackiftekhar/IQKeyboardManager
IQKeyboardManager 的初始化
当 IQKeyboardManager 初始化的时候,它做了这么几件事情:
1. 监听有关键盘的通知q
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];
2. 注册与 UITextField 以及 UITextView 有关的通知
[self registerTextFieldViewClass:[UITextField class]
didBeginEditingNotificationName:UITextFieldTextDidBeginEditingNotification
didEndEditingNotificationName:UITextFieldTextDidEndEditingNotification];
[self registerTextFieldViewClass:[UITextView class]
didBeginEditingNotificationName:UITextViewTextDidBeginEditingNotification
didEndEditingNotificationName:UITextViewTextDidEndEditingNotification];
调用的方法将通知绑定到了 textFieldViewDidBeginEditing: 和 textFieldViewDidEndEditing: 方法上
- (void)registerTextFieldViewClass:(nonnull Class)aClass
didBeginEditingNotificationName:(nonnull NSString *)didBeginEditingNotificationName
didEndEditingNotificationName:(nonnull NSString *)didEndEditingNotificationName {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldViewDidBeginEditing:) name:didBeginEditingNotificationName object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldViewDidEndEditing:) name:didEndEditingNotificationName object:nil];
}
3. 初始化一个 UITapGestureRecognizer,在点击 UITextField 对应的 UIWindow 的时候,收起键盘
strongSelf.tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapRecognized:)];
- (void)tapRecognized:(UITapGestureRecognizer*)gesture {
if (gesture.state == UIGestureRecognizerStateEnded)
[self resignFirstResponder];
}
4. 初始化一些默认属性,例如键盘距离、覆写键盘的样式等
strongSelf.animationDuration = 0.25;
strongSelf.animationCurve = UIViewAnimationCurveEaseInOut;
[self setKeyboardDistanceFromTextField:10.0];
[self setShouldPlayInputClicks:YES];
[self setShouldResignOnTouchOutside:NO];
[self setOverrideKeyboardAppearance:NO];
[self setKeyboardAppearance:UIKeyboardAppearanceDefault];
[self setEnableAutoToolbar:YES];
[self setPreventShowingBottomBlankSpace:YES];
[self setShouldShowTextFieldPlaceholder:YES];
[self setToolbarManageBehaviour:IQAutoToolbarBySubviews];
[self setLayoutIfNeededOnUpdate:NO];
5. 设置不需要解决键盘遮挡问题的类
strongSelf.disabledDistanceHandlingClasses = [[NSMutableSet alloc] initWithObjects:[UITableViewController class], nil];
strongSelf.enabledDistanceHandlingClasses = [[NSMutableSet alloc] init];
strongSelf.disabledToolbarClasses = [[NSMutableSet alloc] init];
strongSelf.enabledToolbarClasses = [[NSMutableSet alloc] init];
strongSelf.toolbarPreviousNextAllowedClasses = [[NSMutableSet alloc] initWithObjects:[UITableView class],[UICollectionView class],[IQPreviousNextView class], nil];
strongSelf.disabledTouchResignedClasses = [[NSMutableSet alloc] init];
strongSelf.enabledTouchResignedClasses = [[NSMutableSet alloc] init];
整个初始化方法大约有几十行的代码,在这里就不再展示整个方法的全部代码了。
基于通知的解决方案
在这里,我们以 UITextField 为例,分析方法的调用流程。
在初始化方法中,我们注册了很多的通知,包括键盘的出现和隐藏,UITextField 开始编辑与结束编辑。
UIKeyboardWillShowNotification
UIKeyboardWillHideNotification
UIKeyboardDidHideNotification
UITextFieldTextDidBeginEditingNotification
UITextFieldTextDidEndEditingNotification
在这些通知响应时,会执行以下的方法:
| Notification | Selector | |:-:|:-:| | UIKeyboardWillShowNotification | @selector(keyboardWillShow:)| | UIKeyboardWillHideNotification | @selector(keyboardWillHide:) | | UIKeyboardDidHideNotification | @selector(keyboardDidHide:) | |UITextFieldTextDidBeginEditingNotification|@selector(textFieldViewDidBeginEditing:)| |UITextFieldTextDidEndEditingNotification|@selector(textFieldViewDidEndEditing:)|
整个解决方案其实都是基于 iOS 中的通知系统的;在事件发生时,调用对应的方法做出响应。
这个库是一个单例,它一旦生效,全项目任何界面都有效。让它生效的代码可以写在任意位置,我写在AppDelegate里。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
IQKeyboardManager *manager = [IQKeyboardManager sharedManager];
manager.enable = YES;
manager.shouldResignOnTouchOutside = YES;
manager.shouldToolbarUsesTextFieldTintColor = YES;
manager.enableAutoToolbar = NO;
return YES;
}
enable控制整个功能是否启用。
shouldResignOnTouchOutside控制点击背景是否收起键盘。
shouldToolbarUsesTextFieldTintColor 控制键盘上的工具条文字颜色是否用户自定义。
enableAutoToolbar控制是否显示键盘上的工具条。
以上设置,就启用了这个库。
使用方法,代码如下:
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) IQKeyboardReturnKeyHandler *returnKeyHandler;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.returnKeyHandler = [[IQKeyboardReturnKeyHandler alloc] initWithViewController:self];
self.returnKeyHandler.lastTextFieldReturnKeyType = UIReturnKeyDone;
self.returnKeyHandler.toolbarManageBehaviour = IQAutoToolbarBySubviews;
}
- (void)dealloc
{
self.returnKeyHandler = nil;
}
@end
设置returnKeyHandler,可以点击键盘上的next键,自动跳到下一个输入框。最后一个输入框点击done自动收起键盘。
运行后,可以看到输入框随着键盘的弹出自动上下浮动。点击背景,键盘收起。全自动了。
这个库默认支持UITextField、UITextView、UIWebView、UIScrollView、UITableView、UICollectionView
最后要注意一点,它可以自动计算多个textField之间的先后顺序,排列依据是看addSubView的先后顺序。