// // TFKeyboardManager.m // WXReader // // Created by 谢腾飞 on 2020/12/3. // Copyright © 2020 xtfei_2011@126.com. All rights reserved. // #import "TFKeyboardManager.h" @interface TFKeyboardManager () @property (nonatomic ,strong) UIToolbar *toolBar; @property (nonatomic ,strong) UIView *baseView; @property (nonatomic ,assign) CGFloat moveDistance; // 被遮挡时,控件需移动距离 @property (nonatomic ,assign) NSValue *superViewFrame; @property (nonatomic ,assign) BOOL isShowkeyboard; // 键盘是否显示 @property (nonatomic ,assign) BOOL isObserver; // 监听是否已添加 @property (nonatomic ,strong) UIBarButtonItem *doneItem; @end @implementation TFKeyboardManager - (instancetype)initObserverWithAdaptiveMovementView:(UIView *)adaptiveMovementView { if (self = [super init]) { self.baseView = adaptiveMovementView; _spacingFromKeyboard = 10; _showToolBar = YES; self.isShowkeyboard = NO; self.isObserver = NO; [self toolBar]; [self startKeyboardObserver]; } return self; } - (void)startKeyboardObserver { if (self.isObserver) { return; } self.isObserver = YES; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(firstResponderDidBeginEditing:) name:UITextViewTextDidBeginEditingNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(firstResponderDidBeginEditing:) name:UITextFieldTextDidBeginEditingNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShowWithNotification:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHideWithNotification:) name:UIKeyboardWillHideNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(switchLanguage) name:Notification_Switch_Language object:nil]; } - (void)switchLanguage { self.doneItem.title = TFLocalizedString(@"完成"); } - (void)stopKeyboardObserver { if (!self.isObserver) { return; } self.isObserver = NO; [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextViewTextDidBeginEditingNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidBeginEditingNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil]; } - (void)firstResponderDidBeginEditing:(NSNotification *)notification { [self setKeyboardToolBarForView:notification.object]; } - (void)keyboardWillShowWithNotification:(NSNotification *)notification { CGRect startFrame = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue]; if (startFrame.size.height > 0 && !self.isShowkeyboard) { self.isShowkeyboard = YES; UITextView *firstResponder = (UITextView *)[self findFirstResponderFromView:self.baseView]; // 屏蔽网页 if ([firstResponder isKindOfClass:NSClassFromString(@"WKContentView")] || !self.baseView || !firstResponder) { return ; } [self setKeyboardToolBarForView:firstResponder]; CGFloat keyboardHeight = [self getKeyboardSizeWithKeyboardInfo:[notification userInfo]].height; CGRect firstResponderFrame = [self.baseView convertRect:firstResponder.frame toView:kMainWindow]; self.moveDistance = CGRectGetMaxY(firstResponderFrame) - (kMainWindow.height - keyboardHeight) + _spacingFromKeyboard; // 没有遮挡输入框 if (self.moveDistance < 0) { self.moveDistance = 0; return; } self.superViewFrame = [NSValue valueWithCGRect:self.baseView.frame]; // 移动后的frame CGRect newSuperViewFrame = CGRectMake(self.baseView.origin.x, CGRectGetMaxY(self.baseView.frame) - self.moveDistance - self.baseView.size.height, self.baseView.size.width, self.baseView.size.height); if (self.keyboardHeightChanged) { NSLog(@"%lf", self.moveDistance); self.keyboardHeightChanged(keyboardHeight, - self.moveDistance, newSuperViewFrame); } } } - (void)keyboardWillHideWithNotification:(NSNotification *)notification { if (self.moveDistance > 0 && self.isShowkeyboard) { if (self.keyboardHeightChanged) { self.keyboardHeightChanged(0, self.moveDistance, self.superViewFrame.CGRectValue); } } self.isShowkeyboard = NO; self.moveDistance = 0; self.superViewFrame = nil; } #pragma mark - tool - (UIView *)findFirstResponderFromView:(UIView *)view { if (view.isFirstResponder) { return view; } for (UIView *subView in view.subviews) { UIView * firstResponder = [self findFirstResponderFromView:subView]; if (firstResponder != nil) { return firstResponder; } } return nil; } - (CGSize)getKeyboardSizeWithKeyboardInfo:(NSDictionary *)keyboardInfo { NSValue *value = [keyboardInfo objectForKey:UIKeyboardFrameEndUserInfoKey]; return [value CGRectValue].size; } - (void)setKeyboardToolBarForView:(UITextView *)view { if (self.showToolBar) { if (!view.inputAccessoryView || view.inputAccessoryView == nil) { view.inputAccessoryView = self.toolBar; } } else { view.inputAccessoryView = nil; } } - (void)setAdaptiveMovementView:(UIView *)adaptiveMovementView { _adaptiveMovementView = adaptiveMovementView; self.baseView = adaptiveMovementView; } - (UIToolbar *)toolBar { if (!_toolBar) { _toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 40)]; _toolBar.barStyle = UIBarStyleDefault; UIBarButtonItem *flexibleSpaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] initWithTitle:TFLocalizedString(@"完成") style:UIBarButtonItemStyleDone target:self action:@selector(hideKeyboard)]; self.doneItem = doneItem; [_toolBar setItems:@[flexibleSpaceItem, doneItem]]; } return _toolBar; } - (void)hideKeyboard { [TFKeyboardManager hideKeyboard]; } + (void)hideKeyboard { [[UIApplication sharedApplication] sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil]; } - (void)dealloc { [self stopKeyboardObserver]; } @end