From fb2900e1851e9b12fbcfaf0c047302fb1ca6ae54 Mon Sep 17 00:00:00 2001 From: Daniel Cohen Gindi Date: Fri, 3 Apr 2020 16:07:24 -0700 Subject: [PATCH] Fixed scrollview inset when RN view is embedded in another view (#27607) Summary: I'm using RNN, which embeds RN view inside native view controllers. On iOS 13, a modal view controller is "floating" and is offset from the top of the screen. This causes the calculation of inset in `KeyboardAvoidingView` incorrect as it mixes local view controller coordinate space, with keyboard's screen coordinate space. ## Changelog [iOS] [Fixed] - Fixed `KeyboardAvoidingView` inset in embedded views (i.e modal view controllers on iOS 13) Pull Request resolved: https://github.com/facebook/react-native/pull/27607 Test Plan: 1. Tested before and after in a simple view controller (should stay the same) 2. Tested before and after in a modal view controller (should be offset before, and fixed after) 3. Repeated no. 2 with each device rotation (upsideDown, landscapeLeft, landscapeRight) Reviewed By: cpojer Differential Revision: D20812231 Pulled By: TheSavior fbshipit-source-id: fbd72739fb7152655028730e284ad26ff4a5da73 --- .../Keyboard/KeyboardAvoidingView.js | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/Libraries/Components/Keyboard/KeyboardAvoidingView.js b/Libraries/Components/Keyboard/KeyboardAvoidingView.js index 7c794ea5e8..061a21bee2 100644 --- a/Libraries/Components/Keyboard/KeyboardAvoidingView.js +++ b/Libraries/Components/Keyboard/KeyboardAvoidingView.js @@ -118,7 +118,28 @@ class KeyboardAvoidingView extends React.Component { _onLayout = (event: ViewLayoutEvent) => { this._frame = event.nativeEvent.layout; - if (!this._initialFrameHeight) { + + let isInitial = !this._initialFrameHeight; + + if (this.viewRef.current !== null) { + // Try to measure inside the window, not the view controller + this.viewRef.current.measureInWindow((x, y, width, height) => { + const frame: ViewLayout = { + x: x, + y: y, + width: width, + height: height, + }; + this._frame = frame; + + if (isInitial) { + // save the initial frame height, before the keyboard is visible + this._initialFrameHeight = frame.height; + } + }); + } + + if (isInitial) { // save the initial frame height, before the keyboard is visible this._initialFrameHeight = this._frame.height; }