Advertisement
Guest User

DaKeyboardControl.m

a guest
Dec 6th, 2013
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //
  2. //  DAKeyboardControl.m
  3. //  DAKeyboardControlExample
  4. //
  5. //  Created by Daniel Amitay on 7/14/12.
  6. //  Copyright (c) 2012 Daniel Amitay. All rights reserved.
  7. //
  8.  
  9. #import "DAKeyboardControl.h"
  10. #import <objc/runtime.h>
  11.  
  12. static char isVisibleKey;
  13.  
  14. static inline UIViewAnimationOptions AnimationOptionsForCurve(UIViewAnimationCurve curve)
  15. {
  16.     switch (curve) {
  17.         case UIViewAnimationCurveEaseInOut:
  18.             return UIViewAnimationOptionCurveEaseInOut;
  19.             break;
  20.         case UIViewAnimationCurveEaseIn:
  21.             return UIViewAnimationOptionCurveEaseIn;
  22.             break;
  23.         case UIViewAnimationCurveEaseOut:
  24.             return UIViewAnimationOptionCurveEaseOut;
  25.             break;
  26.         case UIViewAnimationCurveLinear:
  27.             return UIViewAnimationOptionCurveLinear;
  28.             break;
  29.            
  30.         default:
  31.             return UIViewAnimationOptionCurveEaseInOut;
  32.             break;
  33.     }
  34. }
  35.  
  36. static char UIViewKeyboardTriggerOffset;
  37. static char UIViewKeyboardDidMoveBlock;
  38. static char UIViewKeyboardActiveInput;
  39. static char UIViewKeyboardActiveView;
  40. static char UIViewKeyboardPanRecognizer;
  41.  
  42. @interface UIView (DAKeyboardControl_Internal) <UIGestureRecognizerDelegate>
  43.  
  44. @property (nonatomic) DAKeyboardDidMoveBlock keyboardDidMoveBlock;
  45. @property (nonatomic, assign) UIResponder *keyboardActiveInput;
  46. @property (nonatomic, assign) UIView *keyboardActiveView;
  47. @property (nonatomic, strong) UIPanGestureRecognizer *keyboardPanRecognizer;
  48.  
  49. @end
  50.  
  51. @implementation UIView (DAKeyboardControl)
  52. @dynamic keyboardTriggerOffset;
  53.  
  54. + (void)load
  55. {
  56.     // Swizzle the 'addSubview:' method to ensure that all input fields
  57.     // have a valid inputAccessoryView upon addition to the view heirarchy
  58.     SEL originalSelector = @selector(addSubview:);
  59.     SEL swizzledSelector = @selector(swizzled_addSubview:);
  60.     Method originalMethod = class_getInstanceMethod(self, originalSelector);
  61.     Method swizzledMethod = class_getInstanceMethod(self, swizzledSelector);
  62.     class_addMethod(self,
  63.                     originalSelector,
  64.                     class_getMethodImplementation(self, originalSelector),
  65.                     method_getTypeEncoding(originalMethod));
  66.     class_addMethod(self,
  67.                     swizzledSelector,
  68.                     class_getMethodImplementation(self, swizzledSelector),
  69.                     method_getTypeEncoding(swizzledMethod));
  70.     method_exchangeImplementations(originalMethod, swizzledMethod);
  71. }
  72.  
  73. #pragma mark - Public Methods
  74.  
  75. - (void)addKeyboardPanningWithActionHandler:(DAKeyboardDidMoveBlock)actionHandler
  76. {
  77.     [self addKeyboardControl:YES actionHandler:actionHandler];
  78. }
  79.  
  80. - (void)addKeyboardNonpanningWithActionHandler:(DAKeyboardDidMoveBlock)actionHandler
  81. {
  82.     [self addKeyboardControl:NO actionHandler:actionHandler];
  83. }
  84.  
  85. - (void)addKeyboardControl:(BOOL)panning actionHandler:(DAKeyboardDidMoveBlock)actionHandler
  86. {
  87.     self.keyboardDidMoveBlock = actionHandler;
  88.    
  89.     // Register for text input notifications
  90.     [[NSNotificationCenter defaultCenter] addObserver:self
  91.                                              selector:@selector(responderDidBecomeActive:)
  92.                                                  name:UITextFieldTextDidBeginEditingNotification
  93.                                                object:nil];
  94.     [[NSNotificationCenter defaultCenter] addObserver:self
  95.                                              selector:@selector(responderDidBecomeActive:)
  96.                                                  name:UITextViewTextDidBeginEditingNotification
  97.                                                object:nil];
  98.    
  99.     // Register for keyboard notifications
  100.     /*[[NSNotificationCenter defaultCenter] addObserver:self
  101.                                              selector:@selector(inputKeyboardWillShow:)
  102.                                                  name:UIKeyboardWillShowNotification
  103.                                                object:nil];
  104.     [[NSNotificationCenter defaultCenter] addObserver:self
  105.                                              selector:@selector(inputKeyboardDidShow:)
  106.                                                  name:UIKeyboardDidShowNotification
  107.                                                object:nil];
  108.     */
  109.     // For the sake of 4.X compatibility
  110.     [[NSNotificationCenter defaultCenter] addObserver:self
  111.                                              selector:@selector(inputKeyboardWillChangeFrame:)
  112.                                                  name:@"UIKeyboardWillChangeFrameNotification"
  113.                                                object:nil];
  114.     [[NSNotificationCenter defaultCenter] addObserver:self
  115.                                              selector:@selector(inputKeyboardDidChangeFrame:)
  116.                                                  name:@"UIKeyboardDidChangeFrameNotification"
  117.                                                object:nil];
  118.    
  119.     [[NSNotificationCenter defaultCenter] addObserver:self
  120.                                              selector:@selector(inputKeyboardWillHide:)
  121.                                                  name:UIKeyboardWillHideNotification
  122.                                                object:nil];
  123.     [[NSNotificationCenter defaultCenter] addObserver:self
  124.                                              selector:@selector(inputKeyboardDidHide:)
  125.                                                  name:UIKeyboardDidHideNotification
  126.                                                object:nil];
  127.    
  128.     if (panning)
  129.     {
  130.         // Register for gesture recognizer calls
  131.         self.keyboardPanRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self
  132.                                                                             action:@selector(panGestureDidChange:)];
  133.         [self.keyboardPanRecognizer setMinimumNumberOfTouches:1];
  134.         [self.keyboardPanRecognizer setDelegate:self];
  135.         [self addGestureRecognizer:self.keyboardPanRecognizer];
  136.     }
  137. }
  138.  
  139. - (CGRect)keyboardFrameInView
  140. {
  141.     if (self.keyboardActiveView)
  142.     {
  143.         CGRect keyboardFrameInView = [self convertRect:self.keyboardActiveView.frame
  144.                                               fromView:self.keyboardActiveView.window];
  145.         return keyboardFrameInView;
  146.     }
  147.     else
  148.     {
  149.         CGRect keyboardFrameInView = CGRectMake(0.0f,
  150.                                                 [[UIScreen mainScreen] bounds].size.height,
  151.                                                 0.0f,
  152.                                                 0.0f);
  153.         return keyboardFrameInView;
  154.     }
  155. }
  156.  
  157. - (void)removeKeyboardControl
  158. {
  159.     // Unregister for text input notifications
  160.     [[NSNotificationCenter defaultCenter] removeObserver:self
  161.                                                     name:UITextFieldTextDidBeginEditingNotification
  162.                                                   object:nil];
  163.     [[NSNotificationCenter defaultCenter] removeObserver:self
  164.                                                     name:UITextViewTextDidBeginEditingNotification
  165.                                                   object:nil];
  166.    
  167.     // Unregister for keyboard notifications
  168.     /*[[NSNotificationCenter defaultCenter] removeObserver:self
  169.                                                     name:UIKeyboardWillShowNotification
  170.                                                   object:nil];
  171.     [[NSNotificationCenter defaultCenter] removeObserver:self
  172.                                                     name:UIKeyboardDidShowNotification
  173.                                                   object:nil];*/
  174.    
  175.     // For the sake of 4.X compatibility
  176.     [[NSNotificationCenter defaultCenter] removeObserver:self
  177.                                                     name:@"UIKeyboardWillChangeFrameNotification"
  178.                                                   object:nil];
  179.     [[NSNotificationCenter defaultCenter] removeObserver:self
  180.                                                     name:@"UIKeyboardDidChangeFrameNotification"
  181.                                                   object:nil];
  182.    
  183.     [[NSNotificationCenter defaultCenter] removeObserver:self
  184.                                                     name:UIKeyboardWillHideNotification
  185.                                                   object:nil];
  186.     [[NSNotificationCenter defaultCenter] removeObserver:self
  187.                                                     name:UIKeyboardDidHideNotification
  188.                                                   object:nil];
  189.    
  190.     // Unregister any gesture recognizer
  191.     [self removeGestureRecognizer:self.keyboardPanRecognizer];
  192.    
  193.     // Release a few properties
  194.     self.keyboardDidMoveBlock = nil;
  195.     self.keyboardActiveInput = nil;
  196.     self.keyboardActiveView = nil;
  197.     self.keyboardPanRecognizer = nil;
  198. }
  199.  
  200. - (void)hideKeyboard
  201. {
  202.     self.keyboardActiveView.hidden = YES;
  203.     self.keyboardActiveView.userInteractionEnabled = NO;
  204.     [self.keyboardActiveInput resignFirstResponder];
  205. }
  206.  
  207. #pragma mark - Input Notifications
  208.  
  209. - (void)responderDidBecomeActive:(NSNotification *)notification
  210. {
  211.     // Grab the active input, it will be used to find the keyboard view later on
  212.     self.keyboardActiveInput = notification.object;
  213.     if (!self.keyboardActiveInput.inputAccessoryView)
  214.     {
  215.         UITextField *textField = (UITextField *)self.keyboardActiveInput;
  216.         if ([textField respondsToSelector:@selector(setInputAccessoryView:)])
  217.         {
  218.             UIView *nullView = [[UIView alloc] initWithFrame:CGRectZero];
  219.             nullView.backgroundColor = [UIColor clearColor];
  220.             textField.inputAccessoryView = nullView;
  221.         }
  222.         self.keyboardActiveInput = (UIResponder *)textField;
  223.         // Force the keyboard active view reset
  224.         [self inputKeyboardDidShow:nil];
  225.     }
  226. }
  227.  
  228. #pragma mark - Keyboard Notifications
  229.  
  230. - (void)inputKeyboardWillShow:(NSNotification *)notification
  231. {
  232.     CGRect keyboardEndFrameWindow;
  233.     [[notification.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] getValue: &keyboardEndFrameWindow];
  234.    
  235.     double keyboardTransitionDuration;
  236.     [[notification.userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&keyboardTransitionDuration];
  237.    
  238.     UIViewAnimationCurve keyboardTransitionAnimationCurve;
  239.     [[notification.userInfo valueForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&keyboardTransitionAnimationCurve];
  240.    
  241.     self.keyboardActiveView.hidden = NO;
  242.    
  243.     CGRect keyboardEndFrameView = [self convertRect:keyboardEndFrameWindow fromView:nil];
  244.    
  245.     if (CGRectIsNull(keyboardEndFrameView)) {
  246.         return;
  247.     }
  248.    
  249.     [UIView animateWithDuration:keyboardTransitionDuration
  250.                           delay:0.0f
  251.                         options:AnimationOptionsForCurve(keyboardTransitionAnimationCurve) | UIViewAnimationOptionBeginFromCurrentState
  252.                      animations:^{
  253.                          if (self.keyboardDidMoveBlock)
  254.                              self.keyboardDidMoveBlock(keyboardEndFrameView);
  255.                      }
  256.                      completion:^(BOOL finished){
  257.                      }];
  258. }
  259.  
  260. - (void)inputKeyboardDidShow:(NSNotification *)notification
  261. {
  262.     //PT change here
  263.     self.keyboardVisible = YES;
  264.     // Grab the keyboard view
  265.     self.keyboardActiveView = self.keyboardActiveInput.inputAccessoryView.superview;
  266.     self.keyboardActiveView.hidden = NO;
  267.    
  268.     // If the active keyboard view could not be found (UITextViews...), try again
  269.     if (!self.keyboardActiveView)
  270.     {
  271.         // Find the first responder on subviews and look re-assign first responder to it
  272.         [self reAssignFirstResponder];
  273.     }
  274. }
  275.  
  276. - (void)inputKeyboardWillChangeFrame:(NSNotification *)notification
  277. {
  278.     CGRect keyboardEndFrameWindow;
  279.     [[notification.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] getValue: &keyboardEndFrameWindow];
  280.    
  281.     double keyboardTransitionDuration;
  282.     [[notification.userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&keyboardTransitionDuration];
  283.    
  284.     UIViewAnimationCurve keyboardTransitionAnimationCurve;
  285.     [[notification.userInfo valueForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&keyboardTransitionAnimationCurve];
  286.    
  287.     CGRect keyboardEndFrameView = [self convertRect:keyboardEndFrameWindow fromView:nil];
  288.    
  289.     if (CGRectIsNull(keyboardEndFrameView)) {
  290.         return;
  291.     }
  292.    
  293.     [UIView animateWithDuration:keyboardTransitionDuration
  294.                           delay:0.0f
  295.                         options:AnimationOptionsForCurve(keyboardTransitionAnimationCurve) | UIViewAnimationOptionBeginFromCurrentState
  296.                      animations:^{
  297.                          if (self.keyboardDidMoveBlock)
  298.                              self.keyboardDidMoveBlock(keyboardEndFrameView);
  299.                      }
  300.                      completion:^(BOOL finished){
  301.                      }];
  302. }
  303.  
  304. - (void)inputKeyboardDidChangeFrame:(NSNotification *)notification
  305. {
  306.     // Nothing to see here
  307. }
  308.  
  309. - (void)inputKeyboardWillHide:(NSNotification *)notification
  310. {
  311.     CGRect keyboardEndFrameWindow;
  312.     [[notification.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] getValue: &keyboardEndFrameWindow];
  313.    
  314.     double keyboardTransitionDuration;
  315.     [[notification.userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&keyboardTransitionDuration];
  316.    
  317.     UIViewAnimationCurve keyboardTransitionAnimationCurve;
  318.     [[notification.userInfo valueForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&keyboardTransitionAnimationCurve];
  319.    
  320.     CGRect keyboardEndFrameView = [self convertRect:keyboardEndFrameWindow fromView:nil];
  321.    
  322.     if (CGRectIsNull(keyboardEndFrameView)) {
  323.         return;
  324.     }
  325.    
  326.     [UIView animateWithDuration:keyboardTransitionDuration
  327.                           delay:0.0f
  328.                         options:AnimationOptionsForCurve(keyboardTransitionAnimationCurve) | UIViewAnimationOptionBeginFromCurrentState
  329.                      animations:^{
  330.                          if (self.keyboardDidMoveBlock)
  331.                              self.keyboardDidMoveBlock(keyboardEndFrameView);
  332.                      }
  333.                      completion:^(BOOL finished){
  334.                      }];
  335. }
  336.  
  337. - (void)inputKeyboardDidHide:(NSNotification *)notification
  338. {
  339.     //PT Change here
  340.     self.keyboardVisible = NO;
  341.    
  342.     self.keyboardActiveView.hidden = NO;
  343.     self.keyboardActiveView.userInteractionEnabled = YES;
  344.     self.keyboardActiveView = nil;
  345. }
  346.  
  347. - (void)observeValueForKeyPath:(NSString *)keyPath
  348.                       ofObject:(id)object
  349.                         change:(NSDictionary *)change
  350.                        context:(void *)context
  351. {
  352.     if([keyPath isEqualToString:@"frame"] && object == self.keyboardActiveView)
  353.     {
  354.         CGRect keyboardEndFrameWindow = [[object valueForKeyPath:keyPath] CGRectValue];
  355.         CGRect keyboardEndFrameView = [self convertRect:keyboardEndFrameWindow fromView:self.keyboardActiveView.window];
  356.         if (self.keyboardDidMoveBlock && !self.keyboardActiveView.hidden)
  357.         {
  358.             self.keyboardDidMoveBlock(keyboardEndFrameView);
  359.         }
  360.     }
  361. }
  362.  
  363. #pragma mark - Touches Management
  364.  
  365. - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
  366. {
  367.     if (gestureRecognizer == self.keyboardPanRecognizer || otherGestureRecognizer == self.keyboardPanRecognizer)
  368.     {
  369.         return YES;
  370.     }
  371.     else
  372.     {
  373.         return NO;
  374.     }
  375. }
  376.  
  377. - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
  378. {
  379.     if (gestureRecognizer == self.keyboardPanRecognizer)
  380.     {
  381.         // Don't allow panning if inside the active input (unless SELF is a UITextView and the receiving view)
  382.         return (![touch.view isFirstResponder] || ([self isKindOfClass:[UITextView class]] && [self isEqual:touch.view]));
  383.     }
  384.     else
  385.     {
  386.         return YES;
  387.     }
  388. }
  389.  
  390. - (void)panGestureDidChange:(UIPanGestureRecognizer *)gesture
  391. {
  392.     if(!self.keyboardActiveView || !self.keyboardActiveInput || self.keyboardActiveView.hidden)
  393.     {
  394.         [self reAssignFirstResponder];
  395.         return;
  396.     }
  397.     else
  398.     {
  399.         self.keyboardActiveView.hidden = NO;
  400.     }
  401.    
  402.     CGFloat keyboardViewHeight = self.keyboardActiveView.bounds.size.height;
  403.     CGFloat keyboardWindowHeight = self.keyboardActiveView.window.bounds.size.height;
  404.     CGPoint touchLocationInKeyboardWindow = [gesture locationInView:self.keyboardActiveView.window];
  405.    
  406.     // If touch is inside trigger offset, then disable keyboard input
  407.     if (touchLocationInKeyboardWindow.y > keyboardWindowHeight - keyboardViewHeight - self.keyboardTriggerOffset)
  408.     {
  409.         self.keyboardActiveView.userInteractionEnabled = NO;
  410.     }
  411.     else
  412.     {
  413.         self.keyboardActiveView.userInteractionEnabled = YES;
  414.     }
  415.    
  416.     switch (gesture.state)
  417.     {
  418.         case UIGestureRecognizerStateBegan:
  419.         {
  420.            
  421.         }
  422.             break;
  423.         case UIGestureRecognizerStateChanged:
  424.         {
  425.             CGRect newKeyboardViewFrame = self.keyboardActiveView.frame;
  426.             newKeyboardViewFrame.origin.y = touchLocationInKeyboardWindow.y + self.keyboardTriggerOffset;
  427.             // Bound the keyboard to the bottom of the screen
  428.             newKeyboardViewFrame.origin.y = MIN(newKeyboardViewFrame.origin.y, keyboardWindowHeight);
  429.             newKeyboardViewFrame.origin.y = MAX(newKeyboardViewFrame.origin.y, keyboardWindowHeight - keyboardViewHeight);
  430.            
  431.             // Only update if the frame has actually changed
  432.             if (newKeyboardViewFrame.origin.y != self.keyboardActiveView.frame.origin.y)
  433.             {                
  434.                 [UIView animateWithDuration:0.0f
  435.                                       delay:0.0f
  436.                                     options:UIViewAnimationOptionTransitionNone | UIViewAnimationOptionBeginFromCurrentState
  437.                                  animations:^{
  438.                                      [self.keyboardActiveView setFrame:newKeyboardViewFrame];
  439.                                      /* Unnecessary now, due to KVO on self.keyboardActiveView
  440.                                      CGRect newKeyboardViewFrameInView = [self convertRect:newKeyboardViewFrame
  441.                                                                                   fromView:self.keyboardActiveView.window];
  442.                                      if (self.keyboardDidMoveBlock)
  443.                                          self.keyboardDidMoveBlock(newKeyboardViewFrameInView);
  444.                                      */
  445.                                  }
  446.                                  completion:^(BOOL finished){
  447.                                  }];
  448.             }
  449.         }
  450.             break;
  451.         case UIGestureRecognizerStateEnded:
  452.         case UIGestureRecognizerStateCancelled:
  453.         {
  454.             CGFloat thresholdHeight = keyboardWindowHeight - keyboardViewHeight - self.keyboardTriggerOffset + 44.0f;
  455.             CGPoint velocity = [gesture velocityInView:self.keyboardActiveView];
  456.             BOOL shouldRecede;
  457.            
  458.             if (touchLocationInKeyboardWindow.y < thresholdHeight || velocity.y < 0)
  459.                 shouldRecede = NO;
  460.             else
  461.                 shouldRecede = YES;
  462.            
  463.             // If the keyboard has only been pushed down 44 pixels or has been
  464.             // panned upwards let it pop back up; otherwise, let it drop down
  465.             CGRect newKeyboardViewFrame = self.keyboardActiveView.frame;
  466.             newKeyboardViewFrame.origin.y = (!shouldRecede ? keyboardWindowHeight - keyboardViewHeight : keyboardWindowHeight);
  467.            
  468.             [UIView animateWithDuration:0.25f
  469.                                   delay:0.0f
  470.                                 options:UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionBeginFromCurrentState
  471.                              animations:^{
  472.                                  [self.keyboardActiveView setFrame:newKeyboardViewFrame];
  473.                                  /* Unnecessary now, due to KVO on self.keyboardActiveView
  474.                                  CGRect newKeyboardViewFrameInView = [self convertRect:newKeyboardViewFrame
  475.                                                                               fromView:self.keyboardActiveView.window];
  476.                                  if (self.keyboardDidMoveBlock)
  477.                                      self.keyboardDidMoveBlock(newKeyboardViewFrameInView);
  478.                                  */
  479.                              }
  480.                              completion:^(BOOL finished){
  481.                                  if (shouldRecede)
  482.                                  {
  483.                                      [self hideKeyboard];
  484.                                  }
  485.                              }];
  486.         }
  487.             break;
  488.         default:
  489.             break;
  490.     }
  491. }
  492.  
  493. #pragma mark - Internal Methods
  494.  
  495. - (void)reAssignFirstResponder
  496. {
  497.     // Find first responder
  498.     UIView *inputView = [self recursiveFindFirstResponder:self];
  499.     if (inputView != nil)
  500.     {
  501.         // Re assign the focus
  502.         [inputView resignFirstResponder];
  503.         [inputView becomeFirstResponder];
  504.     }
  505. }
  506.  
  507. - (UIView *)recursiveFindFirstResponder:(UIView *)view
  508. {
  509.     if ([view isFirstResponder])
  510.     {
  511.         return view;
  512.     }
  513.     UIView *found = nil;
  514.     for (UIView *v in view.subviews)
  515.     {
  516.         found = [self recursiveFindFirstResponder:v];
  517.         if (found)
  518.         {
  519.             break;
  520.         }
  521.     }
  522.     return found;
  523. }
  524.  
  525. - (void)swizzled_addSubview:(UIView *)subview
  526. {
  527.     if ([subview isKindOfClass:[UITextView class]] || [subview isKindOfClass:[UITextField class]])
  528.     {
  529.         if (!subview.inputAccessoryView)
  530.         {
  531.             UITextField *textField = (UITextField *)subview;
  532.             if ([textField respondsToSelector:@selector(setInputAccessoryView:)])
  533.             {
  534.                 UIView *nullView = [[UIView alloc] initWithFrame:CGRectZero];
  535.                 nullView.backgroundColor = [UIColor clearColor];
  536.                 textField.inputAccessoryView = nullView;
  537.             }
  538.         }
  539.     }
  540.     [self swizzled_addSubview:subview];
  541. }
  542.  
  543. #pragma mark - Property Methods
  544.  
  545. - (DAKeyboardDidMoveBlock)keyboardDidMoveBlock
  546. {
  547.     return objc_getAssociatedObject(self,
  548.                                     &UIViewKeyboardDidMoveBlock);
  549. }
  550.  
  551. - (void)setKeyboardDidMoveBlock:(DAKeyboardDidMoveBlock)keyboardDidMoveBlock
  552. {
  553.     [self willChangeValueForKey:@"keyboardDidMoveBlock"];
  554.     objc_setAssociatedObject(self,
  555.                              &UIViewKeyboardDidMoveBlock,
  556.                              keyboardDidMoveBlock,
  557.                              OBJC_ASSOCIATION_COPY);
  558.     [self didChangeValueForKey:@"keyboardDidMoveBlock"];
  559. }
  560.  
  561. - (CGFloat)keyboardTriggerOffset
  562. {
  563.     NSNumber *keyboardTriggerOffsetNumber = objc_getAssociatedObject(self,
  564.                                                                      &UIViewKeyboardTriggerOffset);
  565.     return [keyboardTriggerOffsetNumber floatValue];
  566. }
  567.  
  568. - (void)setKeyboardTriggerOffset:(CGFloat)keyboardTriggerOffset
  569. {
  570.     [self willChangeValueForKey:@"keyboardTriggerOffset"];
  571.     objc_setAssociatedObject(self,
  572.                              &UIViewKeyboardTriggerOffset,
  573.                              [NSNumber numberWithFloat:keyboardTriggerOffset],
  574.                              OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  575.     [self didChangeValueForKey:@"keyboardTriggerOffset"];
  576. }
  577.  
  578. - (UIResponder *)keyboardActiveInput
  579. {
  580.     return objc_getAssociatedObject(self,
  581.                                     &UIViewKeyboardActiveInput);
  582. }
  583.  
  584. - (void)setKeyboardActiveInput:(UIResponder *)keyboardActiveInput
  585. {
  586.     [self willChangeValueForKey:@"keyboardActiveInput"];
  587.     objc_setAssociatedObject(self,
  588.                              &UIViewKeyboardActiveInput,
  589.                              keyboardActiveInput,
  590.                              OBJC_ASSOCIATION_ASSIGN);
  591.     [self didChangeValueForKey:@"keyboardActiveInput"];
  592. }
  593.  
  594. - (UIView *)keyboardActiveView
  595. {
  596.     return objc_getAssociatedObject(self,
  597.                                     &UIViewKeyboardActiveView);
  598. }
  599.  
  600. - (void)setKeyboardActiveView:(UIView *)keyboardActiveView
  601. {
  602.     [self willChangeValueForKey:@"keyboardActiveView"];
  603.     [self.keyboardActiveView removeObserver:self
  604.                                  forKeyPath:@"frame"];
  605.     if (keyboardActiveView)
  606.     {
  607.         [keyboardActiveView addObserver:self
  608.                              forKeyPath:@"frame"
  609.                                 options:0
  610.                                 context:NULL];
  611.     }
  612.     objc_setAssociatedObject(self,
  613.                              &UIViewKeyboardActiveView,
  614.                              keyboardActiveView,
  615.                              OBJC_ASSOCIATION_ASSIGN);
  616.     [self didChangeValueForKey:@"keyboardActiveView"];
  617. }
  618.  
  619. - (UIPanGestureRecognizer *)keyboardPanRecognizer
  620. {
  621.     return objc_getAssociatedObject(self,
  622.                                     &UIViewKeyboardPanRecognizer);
  623. }
  624.  
  625. - (void)setKeyboardPanRecognizer:(UIPanGestureRecognizer *)keyboardPanRecognizer
  626. {
  627.     [self willChangeValueForKey:@"keyboardPanRecognizer"];
  628.     objc_setAssociatedObject(self,
  629.                              &UIViewKeyboardPanRecognizer,
  630.                              keyboardPanRecognizer,
  631.                              OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  632.     [self didChangeValueForKey:@"keyboardPanRecognizer"];
  633. }
  634.  
  635. #pragma mark - PT getter setter
  636. -(void)setKeyboardVisible:(BOOL)keyboardVisible {
  637.    
  638.     objc_setAssociatedObject(self, &isVisibleKey, [NSNumber numberWithBool:keyboardVisible], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  639.    
  640. }
  641.  
  642. -(BOOL)isKeyboardVisible {
  643.    
  644.     return [objc_getAssociatedObject(self, &isVisibleKey) boolValue];
  645. }
  646.  
  647. @end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement