diff --git a/ios/keyboardObserver/REAKeyboardEventObserver.m b/ios/keyboardObserver/REAKeyboardEventObserver.m index f6dc92a9623..7fdcd64f24f 100644 --- a/ios/keyboardObserver/REAKeyboardEventObserver.m +++ b/ios/keyboardObserver/REAKeyboardEventObserver.m @@ -28,6 +28,13 @@ - (instancetype)init _nextListenerId = @0; _state = UNKNOWN; _shouldInvalidateDisplayLink = false; + + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + + [notificationCenter addObserver:self + selector:@selector(clearListeners) + name:RCTBridgeDidInvalidateModulesNotification + object:nil]; return self; } @@ -81,8 +88,10 @@ - (void)unsubscribeFromKeyboardEvents:(int)listenerId - (void)runAnimation { - displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateKeyboardFrame)]; - [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; + if (!displayLink) { + displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateKeyboardFrame)]; + [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; + } } - (void)stopAnimation @@ -188,7 +197,10 @@ - (void)unsubscribeFromKeyboardEvents:(int)listenerId NSNumber *_listenerId = [NSNumber numberWithInt:listenerId]; [self->_listeners removeObjectForKey:_listenerId]; if ([self->_listeners count] == 0) { - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidHideNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidShowNotification object:nil]; } }); } @@ -207,6 +219,16 @@ - (void)recognizeInitialKeyboardState }); } +- (void)clearListeners +{ + RCTUnsafeExecuteOnMainQueueSync(^() { + [self->_listeners removeAllObjects]; + [self->displayLink invalidate]; + self->displayLink = nil; + [[NSNotificationCenter defaultCenter] removeObserver:self]; + }); +} + #endif @end diff --git a/ios/native/NativeProxy.mm b/ios/native/NativeProxy.mm index 8d673dbafef..2417f45be49 100644 --- a/ios/native/NativeProxy.mm +++ b/ios/native/NativeProxy.mm @@ -292,16 +292,16 @@ static id convertJSIValueToObjCObject(jsi::Runtime &runtime, const jsi::Value &v // keyboard events - static REAKeyboardEventObserver *keyboardObserver = [[REAKeyboardEventObserver alloc] init]; + REAKeyboardEventObserver *keyboardObserver = [[REAKeyboardEventObserver alloc] init]; auto subscribeForKeyboardEventsFunction = - [](std::function keyboardEventDataUpdater, bool isStatusBarTranslucent) { + [=](std::function keyboardEventDataUpdater, bool isStatusBarTranslucent) { // ignore isStatusBarTranslucent - it's Android only return [keyboardObserver subscribeForKeyboardEvents:^(int keyboardState, int height) { keyboardEventDataUpdater(keyboardState, height); }]; }; - auto unsubscribeFromKeyboardEventsFunction = [](int listenerId) { + auto unsubscribeFromKeyboardEventsFunction = [=](int listenerId) { [keyboardObserver unsubscribeFromKeyboardEvents:listenerId]; }; // end keyboard events