UIViewController+LZBKeyBoardObserver.m 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. //
  2. // UIViewController+LZBKeyBoardObserver.m
  3. // LZBKeyBoardView
  4. //
  5. // demo地址:https://github.com/lzbgithubcode/LZBKeyBoardView.git
  6. // Created by zibin on 16/11/30.
  7. // Copyright © 2016年 apple. All rights reserved.
  8. //
  9. #import "UIViewController+LZBKeyBoardObserver.h"
  10. #import <objc/runtime.h>
  11. CGFloat _lzb_keyBoard_DefaultMargin = lzb_settingKeyBoard_DefaultMargin;
  12. static NSObject *_keyboardWillShowObser;
  13. static NSObject *_keyboardWillHideObser;
  14. @implementation UIViewController (LZBKeyBoardObserver)
  15. #pragma mark - API
  16. - (void)lzb_addKeyBoardObserverAutoAdjustHeight
  17. {
  18. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(youpaifkeyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
  19. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(youpaifkeyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
  20. }
  21. - (void)lzb_removeKeyBoardObserver
  22. {
  23. [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
  24. [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
  25. //键盘手势
  26. [[NSNotificationCenter defaultCenter] removeObserver:_keyboardWillShowObser name:UIKeyboardWillShowNotification object:nil];
  27. [[NSNotificationCenter defaultCenter] removeObserver:_keyboardWillHideObser name:UIKeyboardWillHideNotification object:nil];
  28. }
  29. - (void)lzb_addKeyBoardTapAnyAutoDismissKeyBoard
  30. {
  31. UITapGestureRecognizer *lzbTap = [[UITapGestureRecognizer alloc] initWithTarget:self
  32. action:@selector(tapAnywhereToDismissKeyboard:)];
  33. NSOperationQueue *mainQuene =[NSOperationQueue mainQueue];
  34. __weak UIViewController *weakSelf = self;
  35. _keyboardWillShowObser=[[NSNotificationCenter defaultCenter]
  36. addObserverForName:UIKeyboardWillShowNotification
  37. object:nil
  38. queue:mainQuene
  39. usingBlock:^(NSNotification * _Nonnull note) {
  40. [weakSelf.view addGestureRecognizer:lzbTap];
  41. }];
  42. _keyboardWillHideObser = [[NSNotificationCenter defaultCenter]
  43. addObserverForName:UIKeyboardWillHideNotification
  44. object:nil
  45. queue:mainQuene
  46. usingBlock:^(NSNotification *note){
  47. [weakSelf.view removeGestureRecognizer:lzbTap];
  48. }];
  49. }
  50. #pragma mark - handel
  51. - (void)tapAnywhereToDismissKeyboard:(UIGestureRecognizer *)gestureRecognizer {
  52. dispatch_async(dispatch_get_main_queue(), ^{
  53. [self.view endEditing:YES];
  54. });
  55. }
  56. - (void)youpaifkeyboardWillShow:(NSNotification *)notification
  57. {
  58. //获取键盘的参数
  59. CGFloat keyboardHeight = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
  60. CGFloat keyboardAnimaitonDuration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];
  61. NSInteger option = [notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
  62. //移除之前的动画
  63. [self.view.layer removeAllAnimations];
  64. UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
  65. //找出第一响应者
  66. UIView *firstResponseView = [self findFirstResponderWithView:self.view];
  67. CGRect rect = [keyWindow convertRect:firstResponseView.frame fromView:firstResponseView.superview];
  68. //计算第一响应者与键盘弹出的差值,滚动距离
  69. CGFloat firstResponseViewMaxY= CGRectGetMaxY(rect);
  70. CGFloat keyBoardY = keyWindow.bounds.size.height - keyboardHeight;
  71. CGFloat keyBoardResponseViewMargin = firstResponseViewMaxY - keyBoardY;
  72. //如果响应者的最大Y值 > 键盘的Y值才滚动
  73. _lzb_keyBoard_DefaultMargin = 0;
  74. if(firstResponseViewMaxY > keyBoardY)
  75. {
  76. //设置lzb_settingKeyBoard_DefaultMargin固定距离(就是滚动后的间距)
  77. _lzb_keyBoard_DefaultMargin = lzb_settingKeyBoard_DefaultMargin;
  78. _lzb_keyBoard_DefaultMargin +=keyBoardResponseViewMargin;
  79. //滚动动画
  80. __weak UIViewController *weakSelf = self;
  81. [UIView animateKeyframesWithDuration:keyboardAnimaitonDuration
  82. delay:0
  83. options:option
  84. animations:^{
  85. CGRect frame = weakSelf.view.frame;
  86. frame.origin.y -= _lzb_keyBoard_DefaultMargin;
  87. weakSelf.view.frame = frame;
  88. } completion:nil];
  89. }
  90. }
  91. - (void)youpaifkeyboardWillHide:(NSNotification *)notification
  92. {
  93. //获取键盘的参数
  94. CGFloat keyboardAnimaitonDuration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];
  95. NSInteger option = [notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
  96. __weak UIViewController *weakSelf = self;
  97. //滚动动画
  98. [UIView animateWithDuration:keyboardAnimaitonDuration
  99. delay:0
  100. options:option
  101. animations:^{
  102. CGRect frame = weakSelf.view.frame;
  103. frame.origin.y += _lzb_keyBoard_DefaultMargin;
  104. weakSelf.view.frame = frame;
  105. }
  106. completion:nil];
  107. //注意:一定要清0,因为不知道下一次响应者是位置
  108. _lzb_keyBoard_DefaultMargin = 0;
  109. }
  110. - (UIView *)findFirstResponderWithView:(UIView *)view
  111. {
  112. if(self.isFirstResponder)
  113. return self.view;
  114. for (UIView *subView in view.subviews)
  115. {
  116. if(subView.isFirstResponder)
  117. return subView;
  118. else
  119. continue;
  120. }
  121. return view;
  122. }
  123. @end