react-native-reanimated icon indicating copy to clipboard operation
react-native-reanimated copied to clipboard

The useAnimatedKeyboard shared value is not receiving the live keyboard height on iOS 26

Open vadivazhagan-capmint opened this issue 3 months ago • 8 comments

Description

On iOS 18.6, the useAnimatedKeyboard shared value progressively updates until it reaches the final keyboard height. As a result, the animated view (mimicking a KeyboardAvoidingView) smoothly slides along with the keyboard.

https://github.com/user-attachments/assets/01113512-2b8d-4fd5-9b6a-a9db658c6d4e

However, on iOS 26.0, useAnimatedKeyboard only updates to the final keyboard height, causing the animated view (KeyboardAvoidingView mimic) to snap directly to the final height after the keyboard has fully opened.

https://github.com/user-attachments/assets/d27f2979-68a2-43eb-ba31-b5d699b98f0d

Steps to reproduce

  1. Clone this repo: https://github.com/vadivazhagan-capmint/reanimated-useAnimatedKeyboard-reproduce.git or copy the code snippet below and wrap it around the view that requires KeyboardAvoidingView.

  2. Run the project on iOS 26.0 and iOS 18.6.

Snippet
import React, { PropsWithChildren } from 'react';
import { ViewStyle } from 'react-native';
import Animated, { useAnimatedKeyboard, useAnimatedStyle } from 'react-native-reanimated';

interface IOwnProps extends PropsWithChildren {
  customStyle?: ViewStyle;
}

const AnimatedKeyboardAvoidingView: React.FC<IOwnProps> = ({
  children,
  customStyle,
}) => {
  const keyboard = useAnimatedKeyboard();
  const footerAnimatedStyle = useAnimatedStyle(() => {
    console.log('[Marker] Animated Keyboard Height', keyboard.height.value)

    return {
      transform: [
        {
          translateY: -keyboard.height.value
        }
      ]
    }
  });
  return (
    <Animated.View style={[customStyle, footerAnimatedStyle]}>
      {children}
    </Animated.View>
  );
};
export default AnimatedKeyboardAvoidingView;

In this example repository, I am using React Native 0.81.4, but the issue occurs regardless of the React Native version on iOS 26.0.

Snack or a link to a repository

https://github.com/vadivazhagan-capmint/reanimated-useAnimatedKeyboard-reproduce

Reanimated version

4.1.0

Worklets version

0.5.1

React Native version

0.78.2

Platforms

iOS

JavaScript runtime

Hermes

Workflow

React Native CLI

Architecture

New Architecture (Fabric renderer)

Build type

No response

Device

Real device, iOS simulator

Host machine

macOS

Device model

No response

Acknowledgements

Yes

vadivazhagan-capmint avatar Sep 22 '25 13:09 vadivazhagan-capmint

I confirm, I encountered the same problem

deniska69 avatar Sep 23 '25 07:09 deniska69

@tjzel can you confirm? I see this in multiple projects

kiprijonas avatar Sep 26 '25 07:09 kiprijonas

Can confirm

mrdnlabs-kevin avatar Oct 09 '25 01:10 mrdnlabs-kevin

Same issue

cubevis avatar Oct 15 '25 12:10 cubevis

I have the same issue. I thought I was not using the hook correctly. I'm using reanimated 3.x.x and iOS 26.1 So this looks like iOS 26 specific issue.

schriker avatar Oct 17 '25 11:10 schriker

Any update on the fix for this issue?

ashwini-ksingh avatar Oct 29 '25 07:10 ashwini-ksingh

Here as well. Work around is just to wrap it in WithTiming but it only fires after the keyboard animation settles

useAnimatedReaction(
    () => keyboard.state.value,
    (currKeyboard, prevKeyboar) => {
      if (!(currKeyboard === 2 && prevKeyboar === 2)) {
        debouncedKeyboardHeight.value =
          Platform.OS === "ios"
            ? withTiming(Math.min(keyboard.height.value, 300), { duration: 500 })
            : Math.min(keyboard.height.value, 300);
      }
    },
  );

daxaxelrod avatar Nov 05 '25 17:11 daxaxelrod

Hey guys!

iOS 26 introduced several breaking changes in keyboard behavior, and there is currently no quick universal fix available. As an alternative, you can use the react-native-keyboard-controller library, which isn't flawless, but can serve as a replacement to handle the new keyboard behavior on iOS 26.

Here are some steps showing what you should do to migrate:

  1. Follow this Getting Started guide to install the library
  2. Implement the following helper hook which will work in a similar way to the Reanimated's useAnimatedKeyboard hook
import { useKeyboardHandler } from 'react-native-keyboard-controller';
import { KeyboardState, useSharedValue } from 'react-native-reanimated';

export function useAnimatedKeyboard() {
  const height = useSharedValue(0);
  const state = useSharedValue(KeyboardState.UNKNOWN);

  useKeyboardHandler(
    {
      onStart: (e) => {
        'worklet';
        state.set(e.height > 0 ? KeyboardState.OPENING : KeyboardState.CLOSING);
      },
      onMove: (e) => {
        'worklet';
        height.set(e.height);
      },
      onEnd: (e) => {
        'worklet';
        state.set(e.height > 0 ? KeyboardState.OPEN : KeyboardState.CLOSED);
        height.set(e.height);
      },
      onInteractive: (e) => {
        'worklet';
        height.set(e.height);
      },
    },
    []
  );

  return { height, state };
}
  1. Use the useAnimatedKeyboard implementation from the point 2. as the replacement for the useAnimatedKeyboard from Reanimated

Please let me know if have any more questions!

MatiPl01 avatar Nov 21 '25 18:11 MatiPl01