Skip to content

Instantly share code, notes, and snippets.

@mattyohe
Created December 23, 2014 21:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattyohe/e1909a82b28edbe0013a to your computer and use it in GitHub Desktop.
Save mattyohe/e1909a82b28edbe0013a to your computer and use it in GitHub Desktop.
#import <UIKit/UIKit.h>
@interface UIScrollView (KeyboardInsets)
- (void)addInsetsForKeyboardHandlers;
- (void)removeInsetsForKeyboardHandlers;
@end
#import "UIScrollView+KeyboardInsets.h"
#import <objc/runtime.h>
@implementation UIScrollView (KeyboardInsets)
#pragma mark - Public Interface
- (void)addInsetsForKeyboardHandlers
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateInsetsForKeyboardWillHideNotification:) name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateInsetsForKeyboardWillShowNotification:) name:UIKeyboardWillShowNotification object:nil];
}
- (void)removeInsetsForKeyboardHandlers
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
}
#pragma mark - Private
- (void)setSavedScrollInsets:(UIEdgeInsets)insets
{
NSValue *insetsValue = [NSValue valueWithUIEdgeInsets:insets];
objc_setAssociatedObject(self, @selector(savedScrollInsets), insetsValue, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIEdgeInsets)savedScrollInsets
{
NSValue *insetsValue = objc_getAssociatedObject(self, @selector(savedScrollInsets));
UIEdgeInsets insets = UIEdgeInsetsZero;
if (insetsValue)
{
insets = [insetsValue UIEdgeInsetsValue];
}
return insets;
}
- (void)setHasSavedScrollInsets:(BOOL)hasSaved
{
NSNumber *hasSavedNumber = [NSNumber numberWithBool:hasSaved];
objc_setAssociatedObject(self, @selector(hasSavedScrollInsets), hasSavedNumber, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)hasSavedScrollInsets
{
NSNumber *hasSavedScrollInsets = objc_getAssociatedObject(self, @selector(hasSavedScrollInsets));
return [hasSavedScrollInsets boolValue];
}
- (void)updateInsetsForKeyboardWillShowNotification:(NSNotification *)notification
{
if (![self hasSavedScrollInsets])
{
[self setSavedScrollInsets:[self contentInset]];
[self setHasSavedScrollInsets:YES];
}
NSDictionary *userInfo = [notification userInfo];
NSTimeInterval animationDuration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
UIViewAnimationOptions animationOptions = [userInfo[UIKeyboardAnimationCurveUserInfoKey] unsignedIntegerValue];
CGRect endingFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect convertedFromView = [self convertRect:endingFrame fromView:nil];
CGFloat height = CGRectGetHeight(self.frame) - CGRectGetMinY(convertedFromView) + [self contentOffset].y;
UIEdgeInsets insets = UIEdgeInsetsMake(0.0, 0.0, height, 0.0);
[UIView animateWithDuration:animationDuration delay:0.0 options:animationOptions animations:^{
[self setScrollIndicatorInsets:insets];
[self setContentInset:insets];
} completion:nil];
}
- (void)updateInsetsForKeyboardWillHideNotification:(NSNotification *)notification
{
NSDictionary *userInfo = [notification userInfo];
NSTimeInterval animationDuration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
UIViewAnimationOptions animationOptions = [userInfo[UIKeyboardAnimationCurveUserInfoKey] unsignedIntegerValue];
[UIView animateWithDuration:animationDuration delay:0.0 options:animationOptions animations:^{
UIEdgeInsets insets = [self savedScrollInsets];
[self setScrollIndicatorInsets:insets];
[self setContentInset:insets];
[self setHasSavedScrollInsets:NO];
} completion:nil];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment