Skip to content

Commit 4b9382c

Browse files
gabrieldonadelfacebook-github-bot
authored andcommitted
fix: KeyboardAvoidingView height when "Prefer Cross-Fade Transitions" is enabled (#34503)
Summary: Fix `KeyboardAvoidingView` height on iOS when "Prefer Cross-Fade Transitions" is enabled by adding an additional check to `_relativeKeyboardHeight` verifying if `prefersCrossFadeTransitions()` is true and `keyboardFrame.screenY` is `0` and treating this special case. The issue was caused by the native RCTKeyboardObserver where the `endFrame` reported by `UIKeyboardWillChangeFrameNotification` returns `height = 0` when Prefer Cross-Fade Transitions" is enabled and unfortunelly there isn't much we can do on the native side to fix it. Closes #31484 Closes #29974 ## Changelog [iOS] [Fixed] - Fix KeyboardAvoidingView height when "Prefer Cross-Fade Transitions" is enabled Pull Request resolved: #34503 Test Plan: **On iOS 14+** 1. Access Settings > "General" > "Accessibility" > "Reduce Motion", enable "Reduce Motion" then enable "Prefer Cross-Fade Transitions". 2. Open the RNTester app and navigate to the KeyboardAvoidingView page 3. Focus and blur inputs and observe the keyboard behaving correctly https://user-images.githubusercontent.com/11707729/186822671-801872be-7db1-4c5c-904b-1987441c1326.mov Reviewed By: jacdebug Differential Revision: D39055213 Pulled By: cipolleschi fbshipit-source-id: fac17cbe02867e0fe522397f6cb59a8b51c1840f
1 parent 7a6f0e4 commit 4b9382c

File tree

1 file changed

+18
-5
lines changed

1 file changed

+18
-5
lines changed

Libraries/Components/Keyboard/KeyboardAvoidingView.js

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import type {
2323
ViewLayoutEvent,
2424
} from '../View/ViewPropTypes';
2525
import type {KeyboardEvent, KeyboardMetrics} from './Keyboard';
26+
import AccessibilityInfo from '../AccessibilityInfo/AccessibilityInfo';
2627

2728
type Props = $ReadOnly<{|
2829
...ViewProps,
@@ -71,12 +72,24 @@ class KeyboardAvoidingView extends React.Component<Props, State> {
7172
this.viewRef = React.createRef();
7273
}
7374

74-
_relativeKeyboardHeight(keyboardFrame: KeyboardMetrics): number {
75+
async _relativeKeyboardHeight(
76+
keyboardFrame: KeyboardMetrics,
77+
): Promise<number> {
7578
const frame = this._frame;
7679
if (!frame || !keyboardFrame) {
7780
return 0;
7881
}
7982

83+
// On iOS when Prefer Cross-Fade Transitions is enabled, the keyboard position
84+
// & height is reported differently (0 instead of Y position value matching height of frame)
85+
if (
86+
Platform.OS === 'ios' &&
87+
keyboardFrame.screenY === 0 &&
88+
(await AccessibilityInfo.prefersCrossFadeTransitions())
89+
) {
90+
return 0;
91+
}
92+
8093
const keyboardY =
8194
keyboardFrame.screenY - (this.props.keyboardVerticalOffset ?? 0);
8295

@@ -90,7 +103,7 @@ class KeyboardAvoidingView extends React.Component<Props, State> {
90103
this._updateBottomIfNecessary();
91104
};
92105

93-
_onLayout = (event: ViewLayoutEvent) => {
106+
_onLayout = async (event: ViewLayoutEvent) => {
94107
const wasFrameNull = this._frame == null;
95108
this._frame = event.nativeEvent.layout;
96109
if (!this._initialFrameHeight) {
@@ -99,22 +112,22 @@ class KeyboardAvoidingView extends React.Component<Props, State> {
99112
}
100113

101114
if (wasFrameNull) {
102-
this._updateBottomIfNecessary();
115+
await this._updateBottomIfNecessary();
103116
}
104117

105118
if (this.props.onLayout) {
106119
this.props.onLayout(event);
107120
}
108121
};
109122

110-
_updateBottomIfNecessary = () => {
123+
_updateBottomIfNecessary = async () => {
111124
if (this._keyboardEvent == null) {
112125
this.setState({bottom: 0});
113126
return;
114127
}
115128

116129
const {duration, easing, endCoordinates} = this._keyboardEvent;
117-
const height = this._relativeKeyboardHeight(endCoordinates);
130+
const height = await this._relativeKeyboardHeight(endCoordinates);
118131

119132
if (this.state.bottom === height) {
120133
return;

0 commit comments

Comments
 (0)