打算花时间系统的学习一下YYKit,并结合YYKit整理一套适合自己的库ZYKit
今天打算先从一个相对独立的模块YYKeyboardManager开始这个系统的学习
YYKeyboardManager中学习到的知识点整理
核心思路
在初始化YYKeyboardManager
时,会注册监听键盘的UIKeyboardWillChangeFrameNotification
,在keyboardFrameWillChangeNotification:
方法中,一方面获取通知传递来的关于键盘的初始信息,另一方面注册监听键盘Frame的改变。一旦keyboardFrameWillChangeNotification
、keyboardFrameDidChangeNotification
、keyboardFrameChanged
这三个方法触发,都会调用notifyAllObservers
来通知外部键盘的尺寸已经发生了改变,并将改变后的信息放在结构体里返回。
知识点
- 如果我们希望一个类只能调用单列方法创建,不能让用户调用
init
、new
等系统自带的创建方式创建,我们可以重载init
和new
方法,并抛出一个异常,同时创建一个_init
方法来协助完成单列的创建
- (instancetype)init {
@throw [NSException exceptionWithName:@"YYKeyboardManager init error" reason:@"Use 'defaultManager' to get instance." userInfo:nil];
return [super init];
}
- (instancetype)_init {
self = [super init];
return self;
}
+ (instancetype)defaultManager {
static YYKeyboardManager *manager;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[self alloc] _init];
});
return manager;
}
- 获取键盘View的方式
在iOS系统中键盘View是UIInputSetHostView
的对象,而在不同的系统版本中,键盘View在键盘Window中的层级是不一致的,我们需要根据在不同系统版本中的层级来获取键盘View
键盘View层级图:
iOS 6/7:
UITextEffectsWindow
UIPeripheralHostView << keyboard
iOS 8:
UITextEffectsWindow
UIInputSetContainerView
UIInputSetHostView << keyboard
iOS 9/10:
UIRemoteKeyboardWindow
UIInputSetContainerView
UIInputSetHostView << keyboard
- NSHashTable与NSMapTable的运用
在YYKeyboardManager
中,运用NSHashTable来存放observer
成员,关于NSHashTable与NSMapTable的详细用法可以在另一篇博客中了解
用法
// Get keyboard manager
YYKeyboardManager *manager = [YYKeyboardManager defaultManager];
// Get keyboard view and window
UIView *view = manager.keyboardView;
UIWindow *window = manager.keyboardWindow;
// Get keyboard status
BOOL visible = manager.keyboardVisible;
CGRect frame = manager.keyboardFrame;
frame = [manager convertRect:frame toView:self.view];
// Track keyboard animation
[manager addObserver:self];
// 在代理方法中做一些布局处理
- (void)keyboardChangedWithTransition:(YYKeyboardTransition)transition {
CGRect fromFrame = [manager convertRect:transition.fromFrame toView:self.view];
CGRect toFrame = [manager convertRect:transition.toFrame toView:self.view];
BOOL fromVisible = transition.fromVisible;
BOOL toVisible = transition.toVisible;
NSTimeInterval animationDuration = transition.animationDuration;
UIViewAnimationCurve curve = transition.animationCurve;
}
欢迎访问我的个人博客