Commit f35b3f9a70a903bfec0345c8e625e2e11dc77a2d

Authored by phong
1 parent 256868a43c

fix bug baseviewcontroller

Showing 8 changed files with 822 additions and 0 deletions Side-by-side Diff

LifeLog/LifeLog/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.h
  1 +//
  2 +// TPKeyboardAvoidingCollectionView.h
  3 +// TPKeyboardAvoiding
  4 +//
  5 +// Created by Michael Tyson on 30/09/2013.
  6 +// Copyright 2015 A Tasty Pixel & The CocoaBots. All rights reserved.
  7 +//
  8 +
  9 +#import <UIKit/UIKit.h>
  10 +#import "UIScrollView+TPKeyboardAvoidingAdditions.h"
  11 +
  12 +@interface TPKeyboardAvoidingCollectionView : UICollectionView <UITextFieldDelegate, UITextViewDelegate>
  13 +- (BOOL)focusNextTextField;
  14 +- (void)scrollToActiveTextField;
  15 +@end
LifeLog/LifeLog/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.m
  1 +//
  2 +// TPKeyboardAvoidingCollectionView.m
  3 +// TPKeyboardAvoiding
  4 +//
  5 +// Created by Michael Tyson on 30/09/2013.
  6 +// Copyright 2015 A Tasty Pixel & The CocoaBots. All rights reserved.
  7 +//
  8 +
  9 +#import "TPKeyboardAvoidingCollectionView.h"
  10 +
  11 +@interface TPKeyboardAvoidingCollectionView () <UITextFieldDelegate, UITextViewDelegate>
  12 +@end
  13 +
  14 +@implementation TPKeyboardAvoidingCollectionView
  15 +
  16 +#pragma mark - Setup/Teardown
  17 +
  18 +- (void)setup {
  19 + if ( [self hasAutomaticKeyboardAvoidingBehaviour] ) return;
  20 +
  21 + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(TPKeyboardAvoiding_keyboardWillShow:) name:UIKeyboardWillChangeFrameNotification object:nil];
  22 + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(TPKeyboardAvoiding_keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
  23 + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollToActiveTextField) name:UITextViewTextDidBeginEditingNotification object:nil];
  24 + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollToActiveTextField) name:UITextFieldTextDidBeginEditingNotification object:nil];
  25 +}
  26 +
  27 +-(id)initWithFrame:(CGRect)frame {
  28 + if ( !(self = [super initWithFrame:frame]) ) return nil;
  29 + [self setup];
  30 + return self;
  31 +}
  32 +
  33 +- (id)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout {
  34 + if ( !(self = [super initWithFrame:frame collectionViewLayout:layout]) ) return nil;
  35 + [self setup];
  36 + return self;
  37 +}
  38 +
  39 +-(void)awakeFromNib {
  40 + [super awakeFromNib];
  41 + [self setup];
  42 +}
  43 +
  44 +-(void)dealloc {
  45 + [[NSNotificationCenter defaultCenter] removeObserver:self];
  46 +#if !__has_feature(objc_arc)
  47 + [super dealloc];
  48 +#endif
  49 +}
  50 +
  51 +
  52 +-(BOOL)hasAutomaticKeyboardAvoidingBehaviour {
  53 + if ( [[[UIDevice currentDevice] systemVersion] integerValue] >= 9
  54 + && [self.delegate isKindOfClass:[UICollectionViewController class]] ) {
  55 + // Theory: It looks like iOS 9's collection views automatically avoid the keyboard. As usual
  56 + // Apple have totally failed to document this anywhere, so this is just a guess.
  57 + return YES;
  58 + }
  59 +
  60 + return NO;
  61 +}
  62 +
  63 +-(void)setFrame:(CGRect)frame {
  64 + [super setFrame:frame];
  65 + [self TPKeyboardAvoiding_updateContentInset];
  66 +}
  67 +
  68 +-(void)setContentSize:(CGSize)contentSize {
  69 + if (CGSizeEqualToSize(contentSize, self.contentSize)) {
  70 + // Prevent triggering contentSize when it's already the same that
  71 + // cause weird infinte scrolling and locking bug
  72 + return;
  73 + }
  74 + [super setContentSize:contentSize];
  75 + [self TPKeyboardAvoiding_updateContentInset];
  76 +}
  77 +
  78 +- (BOOL)focusNextTextField {
  79 + return [self TPKeyboardAvoiding_focusNextTextField];
  80 +
  81 +}
  82 +- (void)scrollToActiveTextField {
  83 + return [self TPKeyboardAvoiding_scrollToActiveTextField];
  84 +}
  85 +
  86 +#pragma mark - Responders, events
  87 +
  88 +-(void)willMoveToSuperview:(UIView *)newSuperview {
  89 + [super willMoveToSuperview:newSuperview];
  90 + if ( !newSuperview ) {
  91 + [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) object:self];
  92 + }
  93 +}
  94 +
  95 +- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
  96 + [[self TPKeyboardAvoiding_findFirstResponderBeneathView:self] resignFirstResponder];
  97 + [super touchesEnded:touches withEvent:event];
  98 +}
  99 +
  100 +-(BOOL)textFieldShouldReturn:(UITextField *)textField {
  101 + if ( ![self focusNextTextField] ) {
  102 + [textField resignFirstResponder];
  103 + }
  104 + return YES;
  105 +}
  106 +
  107 +-(void)layoutSubviews {
  108 + [super layoutSubviews];
  109 + [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) object:self];
  110 + [self performSelector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) withObject:self afterDelay:0.1];
  111 +}
  112 +
  113 +@end
LifeLog/LifeLog/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.h
  1 +//
  2 +// TPKeyboardAvoidingScrollView.h
  3 +// TPKeyboardAvoiding
  4 +//
  5 +// Created by Michael Tyson on 30/09/2013.
  6 +// Copyright 2015 A Tasty Pixel. All rights reserved.
  7 +//
  8 +
  9 +#import <UIKit/UIKit.h>
  10 +#import "UIScrollView+TPKeyboardAvoidingAdditions.h"
  11 +
  12 +@interface TPKeyboardAvoidingScrollView : UIScrollView <UITextFieldDelegate, UITextViewDelegate>
  13 +- (void)contentSizeToFit;
  14 +- (BOOL)focusNextTextField;
  15 +- (void)scrollToActiveTextField;
  16 +@end
LifeLog/LifeLog/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.m
  1 +//
  2 +// TPKeyboardAvoidingScrollView.m
  3 +// TPKeyboardAvoiding
  4 +//
  5 +// Created by Michael Tyson on 30/09/2013.
  6 +// Copyright 2015 A Tasty Pixel. All rights reserved.
  7 +//
  8 +
  9 +#import "TPKeyboardAvoidingScrollView.h"
  10 +
  11 +@interface TPKeyboardAvoidingScrollView () <UITextFieldDelegate, UITextViewDelegate>
  12 +@end
  13 +
  14 +@implementation TPKeyboardAvoidingScrollView
  15 +
  16 +#pragma mark - Setup/Teardown
  17 +
  18 +- (void)setup {
  19 + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(TPKeyboardAvoiding_keyboardWillShow:) name:UIKeyboardWillChangeFrameNotification object:nil];
  20 + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(TPKeyboardAvoiding_keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
  21 + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollToActiveTextField) name:UITextViewTextDidBeginEditingNotification object:nil];
  22 + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollToActiveTextField) name:UITextFieldTextDidBeginEditingNotification object:nil];
  23 +}
  24 +
  25 +-(id)initWithFrame:(CGRect)frame {
  26 + if ( !(self = [super initWithFrame:frame]) ) return nil;
  27 + [self setup];
  28 + return self;
  29 +}
  30 +
  31 +-(void)awakeFromNib {
  32 + [super awakeFromNib];
  33 + [self setup];
  34 +}
  35 +
  36 +-(void)dealloc {
  37 + [[NSNotificationCenter defaultCenter] removeObserver:self];
  38 +#if !__has_feature(objc_arc)
  39 + [super dealloc];
  40 +#endif
  41 +}
  42 +
  43 +-(void)setFrame:(CGRect)frame {
  44 + [super setFrame:frame];
  45 + [self TPKeyboardAvoiding_updateContentInset];
  46 +}
  47 +
  48 +-(void)setContentSize:(CGSize)contentSize {
  49 + [super setContentSize:contentSize];
  50 + [self TPKeyboardAvoiding_updateFromContentSizeChange];
  51 +}
  52 +
  53 +- (void)contentSizeToFit {
  54 + self.contentSize = [self TPKeyboardAvoiding_calculatedContentSizeFromSubviewFrames];
  55 +}
  56 +
  57 +- (BOOL)focusNextTextField {
  58 + return [self TPKeyboardAvoiding_focusNextTextField];
  59 +
  60 +}
  61 +- (void)scrollToActiveTextField {
  62 + return [self TPKeyboardAvoiding_scrollToActiveTextField];
  63 +}
  64 +
  65 +#pragma mark - Responders, events
  66 +
  67 +-(void)willMoveToSuperview:(UIView *)newSuperview {
  68 + [super willMoveToSuperview:newSuperview];
  69 + if ( !newSuperview ) {
  70 + [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) object:self];
  71 + }
  72 +}
  73 +
  74 +- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
  75 + [[self TPKeyboardAvoiding_findFirstResponderBeneathView:self] resignFirstResponder];
  76 + [super touchesEnded:touches withEvent:event];
  77 +}
  78 +
  79 +-(BOOL)textFieldShouldReturn:(UITextField *)textField {
  80 + if ( ![self focusNextTextField] ) {
  81 + [textField resignFirstResponder];
  82 + }
  83 + return YES;
  84 +}
  85 +
  86 +-(void)layoutSubviews {
  87 + [super layoutSubviews];
  88 + [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) object:self];
  89 + [self performSelector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) withObject:self afterDelay:0.1];
  90 +}
  91 +
  92 +@end
LifeLog/LifeLog/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.h
  1 +//
  2 +// TPKeyboardAvoidingTableView.h
  3 +// TPKeyboardAvoiding
  4 +//
  5 +// Created by Michael Tyson on 30/09/2013.
  6 +// Copyright 2015 A Tasty Pixel. All rights reserved.
  7 +//
  8 +
  9 +#import <UIKit/UIKit.h>
  10 +#import "UIScrollView+TPKeyboardAvoidingAdditions.h"
  11 +
  12 +@interface TPKeyboardAvoidingTableView : UITableView <UITextFieldDelegate, UITextViewDelegate>
  13 +- (BOOL)focusNextTextField;
  14 +- (void)scrollToActiveTextField;
  15 +@end
LifeLog/LifeLog/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.m
  1 +//
  2 +// TPKeyboardAvoidingTableView.m
  3 +// TPKeyboardAvoiding
  4 +//
  5 +// Created by Michael Tyson on 30/09/2013.
  6 +// Copyright 2015 A Tasty Pixel. All rights reserved.
  7 +//
  8 +
  9 +#import "TPKeyboardAvoidingTableView.h"
  10 +
  11 +@interface TPKeyboardAvoidingTableView () <UITextFieldDelegate, UITextViewDelegate>
  12 +@end
  13 +
  14 +@implementation TPKeyboardAvoidingTableView
  15 +
  16 +#pragma mark - Setup/Teardown
  17 +
  18 +- (void)setup {
  19 + if ( [self hasAutomaticKeyboardAvoidingBehaviour] ) return;
  20 +
  21 + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(TPKeyboardAvoiding_keyboardWillShow:) name:UIKeyboardWillChangeFrameNotification object:nil];
  22 + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(TPKeyboardAvoiding_keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
  23 + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollToActiveTextField) name:UITextViewTextDidBeginEditingNotification object:nil];
  24 + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollToActiveTextField) name:UITextFieldTextDidBeginEditingNotification object:nil];
  25 +}
  26 +
  27 +-(id)initWithFrame:(CGRect)frame {
  28 + if ( !(self = [super initWithFrame:frame]) ) return nil;
  29 + [self setup];
  30 + return self;
  31 +}
  32 +
  33 +-(id)initWithFrame:(CGRect)frame style:(UITableViewStyle)withStyle {
  34 + if ( !(self = [super initWithFrame:frame style:withStyle]) ) return nil;
  35 + [self setup];
  36 + return self;
  37 +}
  38 +
  39 +-(void)awakeFromNib {
  40 + [super awakeFromNib];
  41 + [self setup];
  42 +}
  43 +
  44 +-(void)dealloc {
  45 + [[NSNotificationCenter defaultCenter] removeObserver:self];
  46 +#if !__has_feature(objc_arc)
  47 + [super dealloc];
  48 +#endif
  49 +}
  50 +
  51 +-(BOOL)hasAutomaticKeyboardAvoidingBehaviour {
  52 + if ( [self.delegate isKindOfClass:[UITableViewController class]] ) {
  53 + // Theory: Apps built using the iOS 8.3 SDK (probably: older SDKs not tested) seem to handle keyboard
  54 + // avoiding automatically with UITableViewController. This doesn't seem to be documented anywhere
  55 + // by Apple, so results obtained only empirically.
  56 + return YES;
  57 + }
  58 +
  59 + return NO;
  60 +}
  61 +
  62 +-(void)setFrame:(CGRect)frame {
  63 + [super setFrame:frame];
  64 + if ( [self hasAutomaticKeyboardAvoidingBehaviour] ) return;
  65 + [self TPKeyboardAvoiding_updateContentInset];
  66 +}
  67 +
  68 +-(void)setContentSize:(CGSize)contentSize {
  69 + if ( [self hasAutomaticKeyboardAvoidingBehaviour] ) {
  70 + [super setContentSize:contentSize];
  71 + return;
  72 + }
  73 + if (CGSizeEqualToSize(contentSize, self.contentSize)) {
  74 + // Prevent triggering contentSize when it's already the same
  75 + // this cause table view to scroll to top on contentInset changes
  76 + return;
  77 + }
  78 + [super setContentSize:contentSize];
  79 + [self TPKeyboardAvoiding_updateContentInset];
  80 +}
  81 +
  82 +- (BOOL)focusNextTextField {
  83 + return [self TPKeyboardAvoiding_focusNextTextField];
  84 +
  85 +}
  86 +- (void)scrollToActiveTextField {
  87 + return [self TPKeyboardAvoiding_scrollToActiveTextField];
  88 +}
  89 +
  90 +#pragma mark - Responders, events
  91 +
  92 +-(void)willMoveToSuperview:(UIView *)newSuperview {
  93 + [super willMoveToSuperview:newSuperview];
  94 + if ( !newSuperview ) {
  95 + [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) object:self];
  96 + }
  97 +}
  98 +
  99 +- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
  100 + [[self TPKeyboardAvoiding_findFirstResponderBeneathView:self] resignFirstResponder];
  101 + [super touchesEnded:touches withEvent:event];
  102 +}
  103 +
  104 +-(BOOL)textFieldShouldReturn:(UITextField *)textField {
  105 + if ( ![self focusNextTextField] ) {
  106 + [textField resignFirstResponder];
  107 + }
  108 + return YES;
  109 +}
  110 +
  111 +-(void)layoutSubviews {
  112 + [super layoutSubviews];
  113 + [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) object:self];
  114 + [self performSelector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) withObject:self afterDelay:0.1];
  115 +}
  116 +
  117 +@end
LifeLog/LifeLog/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.h
  1 +//
  2 +// UIScrollView+TPKeyboardAvoidingAdditions.h
  3 +// TPKeyboardAvoiding
  4 +//
  5 +// Created by Michael Tyson on 30/09/2013.
  6 +// Copyright 2015 A Tasty Pixel. All rights reserved.
  7 +//
  8 +
  9 +#import <UIKit/UIKit.h>
  10 +
  11 +@interface UIScrollView (TPKeyboardAvoidingAdditions)
  12 +- (BOOL)TPKeyboardAvoiding_focusNextTextField;
  13 +- (void)TPKeyboardAvoiding_scrollToActiveTextField;
  14 +
  15 +- (void)TPKeyboardAvoiding_keyboardWillShow:(NSNotification*)notification;
  16 +- (void)TPKeyboardAvoiding_keyboardWillHide:(NSNotification*)notification;
  17 +- (void)TPKeyboardAvoiding_updateContentInset;
  18 +- (void)TPKeyboardAvoiding_updateFromContentSizeChange;
  19 +- (void)TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:(UIView*)view;
  20 +- (UIView*)TPKeyboardAvoiding_findFirstResponderBeneathView:(UIView*)view;
  21 +-(CGSize)TPKeyboardAvoiding_calculatedContentSizeFromSubviewFrames;
  22 +@end
LifeLog/LifeLog/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.m
  1 +//
  2 +// UIScrollView+TPKeyboardAvoidingAdditions.m
  3 +// TPKeyboardAvoiding
  4 +//
  5 +// Created by Michael Tyson on 30/09/2013.
  6 +// Copyright 2015 A Tasty Pixel. All rights reserved.
  7 +//
  8 +
  9 +#import "UIScrollView+TPKeyboardAvoidingAdditions.h"
  10 +#import "TPKeyboardAvoidingScrollView.h"
  11 +#import <objc/runtime.h>
  12 +
  13 +static const CGFloat kCalculatedContentPadding = 10;
  14 +static const CGFloat kMinimumScrollOffsetPadding = 20;
  15 +
  16 +static NSString * const kUIKeyboardAnimationDurationUserInfoKey = @"UIKeyboardAnimationDurationUserInfoKey";
  17 +
  18 +static const int kStateKey;
  19 +
  20 +#define _UIKeyboardFrameEndUserInfoKey (&UIKeyboardFrameEndUserInfoKey != NULL ? UIKeyboardFrameEndUserInfoKey : @"UIKeyboardBoundsUserInfoKey")
  21 +
  22 +@interface TPKeyboardAvoidingState : NSObject
  23 +@property (nonatomic, assign) UIEdgeInsets priorInset;
  24 +@property (nonatomic, assign) UIEdgeInsets priorScrollIndicatorInsets;
  25 +@property (nonatomic, assign) BOOL keyboardVisible;
  26 +@property (nonatomic, assign) CGRect keyboardRect;
  27 +@property (nonatomic, assign) CGSize priorContentSize;
  28 +@property (nonatomic, assign) BOOL priorPagingEnabled;
  29 +@property (nonatomic, assign) BOOL ignoringNotifications;
  30 +@property (nonatomic, assign) BOOL keyboardAnimationInProgress;
  31 +@property (nonatomic, assign) CGFloat animationDuration;
  32 +@end
  33 +
  34 +@implementation UIScrollView (TPKeyboardAvoidingAdditions)
  35 +
  36 +- (TPKeyboardAvoidingState*)keyboardAvoidingState {
  37 + TPKeyboardAvoidingState *state = objc_getAssociatedObject(self, &kStateKey);
  38 + if ( !state ) {
  39 + state = [[TPKeyboardAvoidingState alloc] init];
  40 + objc_setAssociatedObject(self, &kStateKey, state, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  41 +#if !__has_feature(objc_arc)
  42 + [state release];
  43 +#endif
  44 + }
  45 + return state;
  46 +}
  47 +
  48 +- (void)TPKeyboardAvoiding_keyboardWillShow:(NSNotification*)notification {
  49 + NSDictionary *info = [notification userInfo];
  50 + TPKeyboardAvoidingState *state = self.keyboardAvoidingState;
  51 +
  52 + state.animationDuration = [[info objectForKey:kUIKeyboardAnimationDurationUserInfoKey] doubleValue];
  53 +
  54 + CGRect keyboardRect = [self convertRect:[[info objectForKey:_UIKeyboardFrameEndUserInfoKey] CGRectValue] fromView:nil];
  55 + if (CGRectIsEmpty(keyboardRect)) {
  56 + return;
  57 + }
  58 +
  59 + if ( state.ignoringNotifications ) {
  60 + return;
  61 + }
  62 +
  63 + state.keyboardRect = keyboardRect;
  64 +
  65 + if ( !state.keyboardVisible ) {
  66 + state.priorInset = self.contentInset;
  67 + state.priorScrollIndicatorInsets = self.scrollIndicatorInsets;
  68 + state.priorPagingEnabled = self.pagingEnabled;
  69 + }
  70 +
  71 + state.keyboardVisible = YES;
  72 + self.pagingEnabled = NO;
  73 +
  74 + if ( [self isKindOfClass:[TPKeyboardAvoidingScrollView class]] ) {
  75 + state.priorContentSize = self.contentSize;
  76 +
  77 + if ( CGSizeEqualToSize(self.contentSize, CGSizeZero) ) {
  78 + // Set the content size, if it's not set. Do not set content size explicitly if auto-layout
  79 + // is being used to manage subviews
  80 + self.contentSize = [self TPKeyboardAvoiding_calculatedContentSizeFromSubviewFrames];
  81 + }
  82 + }
  83 +
  84 + // Delay until a future run loop such that the cursor position is available in a text view
  85 + // In other words, it's not available (specifically, the prior cursor position is returned) when the first keyboard position change notification fires
  86 + // NOTE: Unfortunately, using dispatch_async(main_queue) did not result in a sufficient-enough delay
  87 + // for the text view's current cursor position to be available
  88 + dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC));
  89 + dispatch_after(delay, dispatch_get_main_queue(), ^{
  90 +
  91 + // Shrink view's inset by the keyboard's height, and scroll to show the text field/view being edited
  92 + [UIView beginAnimations:nil context:NULL];
  93 +
  94 + [UIView setAnimationDelegate:self];
  95 + [UIView setAnimationWillStartSelector:@selector(keyboardViewAppear:context:)];
  96 + [UIView setAnimationDidStopSelector:@selector(keyboardViewDisappear:finished:context:)];
  97 +
  98 + [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
  99 + [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]];
  100 +
  101 + UIView *firstResponder = [self TPKeyboardAvoiding_findFirstResponderBeneathView:self];
  102 + if ( firstResponder ) {
  103 +