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: KeyboardAvoidingView height when "Prefer Cross-Fade Transitions" is enabled #34503

Closed
Changes from 1 commit
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
19 changes: 16 additions & 3 deletions Libraries/Components/Keyboard/KeyboardAvoidingView.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import type {
ViewLayoutEvent,
} from '../View/ViewPropTypes';
import type {KeyboardEvent, KeyboardMetrics} from './Keyboard';
import AccessibilityInfo from '../AccessibilityInfo/AccessibilityInfo';

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

_relativeKeyboardHeight(keyboardFrame: KeyboardMetrics): number {
async _relativeKeyboardHeight(
keyboardFrame: KeyboardMetrics,
): 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);

Expand Down Expand Up @@ -107,14 +120,14 @@ class KeyboardAvoidingView extends React.Component<Props, State> {
}
};

_updateBottomIfNecessary = () => {
_updateBottomIfNecessary = async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Call sites for function _updateBottomIfNecessary is not using await, as a side effect the function call this.props.onLayout(event) now won't wait for _updateBottomIfNecessary to finish.

As per the doc, This event is fired immediately once the layout has been calculated

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohh good point, I added an await to the _updateBottomIfNecessary call to ensure everything is properly calculated before the this.props.onLayout function is called.

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;
Expand Down