mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
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 https://github.com/facebook/react-native/issues/31484 Closes https://github.com/facebook/react-native/issues/29974 [iOS] [Fixed] - Fix KeyboardAvoidingView height when "Prefer Cross-Fade Transitions" is enabled Pull Request resolved: https://github.com/facebook/react-native/pull/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
This commit is contained in:
committed by
Dmitry Rykun
parent
047a149279
commit
ec0049b008
@@ -23,6 +23,7 @@ import type {
|
||||
ViewLayoutEvent,
|
||||
} from '../View/ViewPropTypes';
|
||||
import type {KeyboardEvent, KeyboardEventCoordinates} from './Keyboard';
|
||||
import AccessibilityInfo from '../AccessibilityInfo/AccessibilityInfo';
|
||||
|
||||
type Props = $ReadOnly<{|
|
||||
...ViewProps,
|
||||
@@ -71,12 +72,24 @@ class KeyboardAvoidingView extends React.Component<Props, State> {
|
||||
this.viewRef = React.createRef();
|
||||
}
|
||||
|
||||
_relativeKeyboardHeight(keyboardFrame: KeyboardEventCoordinates): number {
|
||||
async _relativeKeyboardHeight(
|
||||
keyboardFrame: KeyboardEventCoordinates,
|
||||
): Promise<number> {
|
||||
const frame = this._frame;
|
||||
if (!frame || !keyboardFrame) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// On iOS when Prefer Cross-Fade Transitions is enabled, the keyboard position
|
||||
// & height is reported differently (0 instead of Y position value matching height of frame)
|
||||
if (
|
||||
Platform.OS === 'ios' &&
|
||||
keyboardFrame.screenY === 0 &&
|
||||
(await AccessibilityInfo.prefersCrossFadeTransitions())
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const keyboardY =
|
||||
keyboardFrame.screenY - (this.props.keyboardVerticalOffset ?? 0);
|
||||
|
||||
@@ -90,7 +103,7 @@ class KeyboardAvoidingView extends React.Component<Props, State> {
|
||||
this._updateBottomIfNecessary();
|
||||
};
|
||||
|
||||
_onLayout = (event: ViewLayoutEvent) => {
|
||||
_onLayout = async (event: ViewLayoutEvent) => {
|
||||
const wasFrameNull = this._frame == null;
|
||||
this._frame = event.nativeEvent.layout;
|
||||
if (!this._initialFrameHeight) {
|
||||
@@ -99,7 +112,7 @@ class KeyboardAvoidingView extends React.Component<Props, State> {
|
||||
}
|
||||
|
||||
if (wasFrameNull) {
|
||||
this._updateBottomIfNecessary();
|
||||
await this._updateBottomIfNecessary();
|
||||
}
|
||||
|
||||
if (this.props.onLayout) {
|
||||
@@ -107,14 +120,14 @@ class KeyboardAvoidingView extends React.Component<Props, State> {
|
||||
}
|
||||
};
|
||||
|
||||
_updateBottomIfNecessary = () => {
|
||||
_updateBottomIfNecessary = async () => {
|
||||
if (this._keyboardEvent == null) {
|
||||
this.setState({bottom: 0});
|
||||
return;
|
||||
}
|
||||
|
||||
const {duration, easing, endCoordinates} = this._keyboardEvent;
|
||||
const height = this._relativeKeyboardHeight(endCoordinates);
|
||||
const height = await this._relativeKeyboardHeight(endCoordinates);
|
||||
|
||||
if (this.state.bottom === height) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user