SPSBKeyboardManager.m 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. //
  2. // SPSBKeyboardManager.m
  3. // 我的社保
  4. //
  5. // Created by shanp on 2021/4/25.
  6. //
  7. #import "SPSBKeyboardManager.h"
  8. #import <JXHMacro.h>
  9. #import <JXHSystemShortcut.h>
  10. #import <objc/runtime.h>
  11. #import "SPSBTextField.h"
  12. #import <JXHGeneralTools.h>
  13. #import "SPSBGeneralManager.h"
  14. @interface SPSBKeyboardManager () {
  15. UIToolbar *_toolbar;
  16. SPSBTextField *_textField;
  17. }
  18. @end
  19. @implementation SPSBKeyboardManager
  20. + (instancetype)alloc {
  21. NSAssert(![self isMemberOfClass:[SPSBKeyboardManager class]], @"SPSBKeyboardManager is singleton, you should not instantiate it directly.");
  22. return [super alloc];
  23. }
  24. + (SPSBKeyboardManager *)shareManager {
  25. static SPSBKeyboardManager *manager = nil;
  26. static dispatch_once_t once;
  27. dispatch_once(&once, ^{
  28. manager = [[super allocWithZone:nil] init];
  29. [manager addKeyboardTool];
  30. });
  31. return manager;
  32. }
  33. + (instancetype)allocWithZone:(struct _NSZone *)zone {
  34. return [self shareManager];
  35. }
  36. - (void)addKeyboardTool {
  37. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
  38. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UITextFieldTextDidBeginEditingNotification object:nil];
  39. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UITextViewTextDidBeginEditingNotification object:nil];
  40. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldDidChange:) name:UITextFieldTextDidChangeNotification object:nil];
  41. _toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, jxh_screenHeight(), jxh_screenWidth(), 44)];
  42. _toolbar.items = @[[[UIBarButtonItem alloc]initWithBarButtonSystemItem: UIBarButtonSystemItemFlexibleSpace target:nil action:nil], [[UIBarButtonItem alloc] initWithTitle:@"完成" style:UIBarButtonItemStylePlain target:self action:@selector(HiddenKeyBoard)]];
  43. _textField = [[SPSBTextField alloc] initWithFrame:CGRectMake(15, 0, jxh_screenWidth() * 2 / 3, 44)];
  44. _textField.enabled = false;
  45. [_toolbar addSubview:_textField];
  46. }
  47. - (void)removeKeyboardTool {
  48. [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillChangeFrameNotification object:nil];
  49. [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidBeginEditingNotification object:nil];
  50. [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextViewTextDidBeginEditingNotification object:nil];
  51. [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil];
  52. _toolbar = nil;
  53. _textField = nil;
  54. }
  55. - (void)keyboardWillShow:(NSNotification *)sender {
  56. UIViewController *vc = jxh_findPresentedViewControllerStartingFrom(spsb_keyWindow().rootViewController);
  57. if (![NSStringFromClass([vc class]) hasPrefix:@"SPSB"]) return;
  58. debugLog(@"-----------%@", sender.userInfo);
  59. id firstResponder;
  60. for (UIWindow *window in jxh_application().windows) {
  61. #pragma clang diagnostic push
  62. #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
  63. SEL f = NSSelectorFromString([NSString stringWithFormat:@"%@%@", @"first", @"Responder"]);
  64. firstResponder = [window performSelector:f];
  65. #pragma clang diagnostic pop
  66. if (firstResponder) {
  67. break;
  68. }
  69. }
  70. if ([firstResponder isKindOfClass:[UITextField class]]) {
  71. UITextField *_firstResponder = firstResponder;
  72. objc_setAssociatedObject(_firstResponder, &kKeyboardKey, _textField, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  73. _textField.placeholder = _firstResponder.placeholder;
  74. _textField.text = _firstResponder.text;
  75. _textField.secureTextEntry = _firstResponder.secureTextEntry;
  76. if ([firstResponder isKindOfClass:[SPSBTextField class]]) {
  77. _textField.spsb_maxCount = ((SPSBTextField *)_firstResponder).spsb_maxCount;
  78. } else {
  79. _textField.spsb_maxCount = 0;
  80. }
  81. if (_firstResponder.inputAccessoryView) {
  82. _firstResponder.inputAccessoryView = nil;
  83. }
  84. _firstResponder.inputAccessoryView = _toolbar;
  85. [_firstResponder reloadInputViews];
  86. } else if ([firstResponder isKindOfClass:[UITextView class]]) {
  87. UITextView *_firstResponder = firstResponder;
  88. _textField.placeholder = @"";
  89. _textField.text = @"";
  90. if (_firstResponder.inputAccessoryView) {
  91. _firstResponder.inputAccessoryView = nil;
  92. }
  93. _firstResponder.inputAccessoryView = _toolbar;
  94. [_firstResponder reloadInputViews];
  95. }
  96. }
  97. static char kKeyboardKey;
  98. - (void)keyboardWillChangeFrame:(NSNotification *)sender {
  99. UIViewController *vc = jxh_findPresentedViewControllerStartingFrom(spsb_keyWindow().rootViewController);
  100. if (![NSStringFromClass([vc class]) hasPrefix:@"SPSB"]) return;
  101. debugLog(@"======================%@", sender.userInfo);
  102. id firstResponder;
  103. for (UIWindow *window in jxh_application().windows) {
  104. #pragma clang diagnostic push
  105. #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
  106. SEL f = NSSelectorFromString([NSString stringWithFormat:@"%@%@", @"first", @"Responder"]);
  107. firstResponder = [window performSelector:f];
  108. #pragma clang diagnostic pop
  109. if (firstResponder) {
  110. break;
  111. }
  112. }
  113. if ([firstResponder isKindOfClass:[UITextField class]]) {
  114. UITextField *_firstResponder = firstResponder;
  115. debugLog(@"%@", _firstResponder);
  116. CGFloat keyboardY = [sender.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].origin.y;
  117. if (keyboardY == jxh_screenHeight()) {
  118. _firstResponder.inputAccessoryView = nil;
  119. }
  120. } else if ([firstResponder isKindOfClass:[UITextView class]]) {
  121. UITextView *_firstResponder = firstResponder;
  122. debugLog(@"%@", _firstResponder);
  123. CGFloat keyboardY = [sender.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].origin.y;
  124. if (keyboardY == jxh_screenHeight()) {
  125. _firstResponder.inputAccessoryView = nil;
  126. }
  127. }
  128. }
  129. - (void)textFieldDidChange:(NSNotification *)sender {
  130. debugLog(@"_____________%@", sender);
  131. UITextField *textField = sender.object;
  132. SPSBTextField *textField1 = objc_getAssociatedObject(textField, &kKeyboardKey);
  133. textField1.text = textField.text;
  134. [textField1 textDidChange];
  135. }
  136. - (void)HiddenKeyBoard {
  137. UIViewController *vc = jxh_findPresentedViewControllerStartingFrom(spsb_keyWindow().rootViewController);
  138. if (![NSStringFromClass([vc class]) hasPrefix:@"SPSB"]) return;
  139. id firstResponder;
  140. for (UIWindow *window in jxh_application().windows) {
  141. #pragma clang diagnostic push
  142. #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
  143. SEL f = NSSelectorFromString([NSString stringWithFormat:@"%@%@", @"first", @"Responder"]);
  144. firstResponder = [window performSelector:f];
  145. #pragma clang diagnostic pop
  146. if (firstResponder) {
  147. [window endEditing:true];
  148. break;
  149. }
  150. }
  151. }
  152. - (void)dealloc {
  153. [self removeKeyboardTool];
  154. }
  155. @end