Sticky footer recipe
To handle complex layouts, where you want to make visible parts of UI inside and outside of scroll component (like scrollable text fields and fixed CTA button), you should manually handle parts that are not in the current focused input's container.
One use case is handling "sticky" CTA button fixed at the bottom of the screen with text fields displayed inside ScrollView
.
To handle button manually, you can use useSoftInputHeightChanged
or combination of useSoftInputShown
and useSoftInputHidden
hooks to apply additional padding for button's container.
Example
export const StickyFooterExample: React.FC = () => {
/**
* You can store additional padding using Reanimated's shared value
*
* If you want to keep it simple, you can instead store it in React's useState
*/
const buttonContainerPaddingValue = useSharedValue(0);
const buttonContainerAnimatedStyle = useAnimatedStyle(() => {
return {
paddingBottom: buttonContainerPaddingValue.value,
};
});
const onFocusEffect = useCallback(() => {
AvoidSoftInput.setAdjustNothing();
return () => {
AvoidSoftInput.setDefaultAppSoftInputMode();
};
}, []);
useFocusEffect(onFocusEffect);
useSoftInputHeightChanged(({ softInputHeight }) => {
/**
* Set/remove additional padding when soft input is visible/hidden
*
* You can save it in Reanimated's shared value and make smooth transition
* or just store it inside React's useState and add padding conditionally in render part
*
* You can also use `useSoftInputShown` & `useSoftInputHidden`
*
* useSoftInputShown(({ softInputHeight }) => {
* buttonContainerPaddingValue.value = withTiming(softInputHeight);
* });
*
* useSoftInputHidden(() => {
* buttonContainerPaddingValue.value = withTiming(0);
* });
*/
buttonContainerPaddingValue.value = withTiming(softInputHeight);
});
return (
<SafeAreaView>
<View>
<ScrollView>
// ... form
<SingleInput />
// ... form
</ScrollView>
</View>
<Animated.View /** here add your additional padding */>
<View>
<Button />
</View>
</Animated.View>
</SafeAreaView>
);
};