Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for react native 0.46.0. #8

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 48 additions & 36 deletions lib/KeyboardTrackingViewManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@
#import "RCTTextField.h"
#endif

#if __has_include(<React/RCTUITextView.h>)
#import <React/RCTUITextView.h>
#else
#import "RCTUITextView.h"
#endif

#if __has_include(<React/RCTUITextField.h>)
#import <React/RCTUITextField.h>
#else
#import "RCTUITextField.h"
#endif

#if __has_include(<React/RCTScrollView.h>)
#import <React/RCTScrollView.h>
#else
Expand Down Expand Up @@ -86,19 +98,19 @@ @implementation KeyboardTrackingView
-(instancetype)init
{
self = [super init];

if (self)
{
[self addObserver:self forKeyPath:@"bounds" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:NULL];
_inputViewsMap = [NSMapTable weakToWeakObjectsMapTable];
_deferedInitializeAccessoryViewsCount = 0;
[ObservingInputAccessoryView sharedInstance].delegate = self;

_manageScrollView = YES;

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(rctContentDidAppearNotification:) name:RCTContentDidAppearNotification object:nil];
}

return self;
}

Expand All @@ -111,7 +123,7 @@ -(RCTRootView*)getRootView
if ([view isKindOfClass:[RCTRootView class]])
break;
}

if ([view isKindOfClass:[RCTRootView class]])
{
return (RCTRootView*)view;
Expand All @@ -129,21 +141,21 @@ -(void)_swizzleWebViewInputAccessory:(UIWebView*)webview
subview = view;
}
}

if(_newClass == nil)
{
NSString* name = [NSString stringWithFormat:@"%@_Tracking_%p", subview.class, self];
_newClass = NSClassFromString(name);

_newClass = objc_allocateClassPair(subview.class, [name cStringUsingEncoding:NSASCIIStringEncoding], 0);
if(!_newClass) return;

Method method = class_getInstanceMethod([UIResponder class], @selector(inputAccessoryView));
class_addMethod(_newClass, @selector(inputAccessoryView), imp_implementationWithBlock(^(id _self){return [ObservingInputAccessoryView sharedInstance];}), method_getTypeEncoding(method));

objc_registerClassPair(_newClass);
}

object_setClass(subview, _newClass);
[subview reloadInputViews];
}
Expand All @@ -152,9 +164,9 @@ - (void)initializeAccessoryViewsAndHandleInsets
{
NSArray<UIView*>* allSubviews = [self getBreadthFirstSubviewsForView:[self getRootView]];
NSMutableArray<RCTScrollView*>* rctScrollViewsArray = [NSMutableArray array];

for (UIView* subview in allSubviews) {

if(_manageScrollView)
{
if(_scrollViewToManage == nil)
Expand All @@ -167,34 +179,34 @@ - (void)initializeAccessoryViewsAndHandleInsets
{
_scrollViewToManage = (UIScrollView*)subview;
}

if(_scrollViewToManage != nil)
{
_scrollIsInverted = CGAffineTransformEqualToTransform(_scrollViewToManage.superview.transform, CGAffineTransformMakeScale(1, -1));
}
}

if([subview isKindOfClass:[RCTScrollView class]])
{
[rctScrollViewsArray addObject:(RCTScrollView*)subview];
}
}

if ([subview isKindOfClass:[RCTTextField class]])
{
[((RCTTextField*)subview) setInputAccessoryView:[ObservingInputAccessoryView sharedInstance]];
[((RCTTextField*)subview) reloadInputViews];
[(RCTUITextField*)[(RCTTextField*)subview backedTextInputView] setInputAccessoryView:[ObservingInputAccessoryView sharedInstance]];
[(RCTUITextField*)[(RCTTextField*)subview backedTextInputView] reloadInputViews];

[_inputViewsMap setObject:subview forKey:@(kInputViewKey)];
}
else if ([subview isKindOfClass:[RCTTextView class]])
{
UITextView *textView = [subview valueForKey:@"_textView"];
UITextView *textView = (RCTUITextView*)[(RCTTextView*)subview backedTextInputView];
if (textView != nil)
{
[textView setInputAccessoryView:[ObservingInputAccessoryView sharedInstance]];
[textView reloadInputViews];

[_inputViewsMap setObject:textView forKey:@(kInputViewKey)];
}
}
Expand All @@ -203,7 +215,7 @@ - (void)initializeAccessoryViewsAndHandleInsets
[self _swizzleWebViewInputAccessory:(UIWebView*)subview];
}
}

for (RCTScrollView *scrollView in rctScrollViewsArray)
{
if(scrollView.scrollView == _scrollViewToManage)
Expand All @@ -213,9 +225,9 @@ - (void)initializeAccessoryViewsAndHandleInsets
break;
}
}

[self _updateScrollViewInsets];

_originalHeight = [ObservingInputAccessoryView sharedInstance].height;
}

Expand All @@ -225,11 +237,11 @@ -(void) deferedInitializeAccessoryViewsAndHandleInsets
{
return;
}

if ([ObservingInputAccessoryView sharedInstance].height == 0 && self.deferedInitializeAccessoryViewsCount < kMaxDeferedInitializeAccessoryViews)
{
self.deferedInitializeAccessoryViewsCount++;

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self deferedInitializeAccessoryViewsAndHandleInsets];
});
Expand All @@ -245,9 +257,9 @@ -(void) deferedInitializeAccessoryViewsAndHandleInsets
-(void)didMoveToWindow
{
[super didMoveToWindow];

self.deferedInitializeAccessoryViewsCount = 0;

[self deferedInitializeAccessoryViewsAndHandleInsets];
}

Expand All @@ -267,17 +279,17 @@ - (NSArray*)getBreadthFirstSubviewsForView:(UIView*)view
{
return nil;
}

NSMutableArray *allSubviews = [NSMutableArray new];
NSMutableArray *queue = [NSMutableArray new];

[allSubviews addObject:view];
[queue addObject:view];

while ([queue count] > 0) {
UIView *current = [queue lastObject];
[queue removeLastObject];

for (UIView *n in current.subviews)
{
[allSubviews addObject:n];
Expand Down Expand Up @@ -315,7 +327,7 @@ - (void)_updateScrollViewInsets
insets.bottom = bottomInset;
}
self.scrollViewToManage.contentInset = insets;

if(self.scrollBehavior == KeyboardTrackingScrollBehaviorScrollToBottomInvertedOnly && _scrollIsInverted)
{
BOOL fisrtTime = [ObservingInputAccessoryView sharedInstance].keyboardHeight == 0 && [ObservingInputAccessoryView sharedInstance].keyboardState == KeyboardStateHidden;
Expand All @@ -331,7 +343,7 @@ - (void)_updateScrollViewInsets
CGFloat insetsDiff = (bottomInset - originalBottomInset) * (self.scrollIsInverted ? -1 : 1);
self.scrollViewToManage.contentOffset = CGPointMake(originalOffset.x, originalOffset.y + insetsDiff);
}

insets = self.scrollViewToManage.scrollIndicatorInsets;
if(self.scrollIsInverted)
{
Expand Down Expand Up @@ -363,7 +375,7 @@ - (void)observingInputAccessoryViewDidChangeFrame:(ObservingInputAccessoryView*)
{
CGFloat accessoryTranslation = MIN(0, -[ObservingInputAccessoryView sharedInstance].keyboardHeight);
self.transform = CGAffineTransformMakeTranslation(0, accessoryTranslation);

[self _updateScrollViewInsets];
}

Expand All @@ -375,7 +387,7 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
return;
}

UIView *inputView = [_inputViewsMap objectForKey:@(kInputViewKey)];
if (inputView != nil && scrollView.contentOffset.y * (self.scrollIsInverted ? -1 : 1) > (self.scrollIsInverted ? scrollView.contentInset.top : scrollView.contentInset.bottom) + 50 && ![inputView isFirstResponder])
{
Expand All @@ -387,7 +399,7 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView
gesture.enabled = YES;
}
}

if([inputView respondsToSelector:@selector(reactWillMakeFirstResponder)])
{
[inputView performSelector:@selector(reactWillMakeFirstResponder)];
Expand Down