작성
·
15
0
윈도우+안드로이드 환경에서 KeyboardAwareScrollView가 동작하지 않아 React Native 문서를 보고 KeyboardAvoidingView component를 사용하려고 시도 했습니다.
import Button from "@/components/CustomButton";
import DescriptionInput from "@/components/DescriptionInput";
import TitleInput from "@/components/TitleInput";
import { useCreatePost } from "@/hooks/queries/useCreatePost";
import useKeyboardOffset from "@/hooks/useKeyboardOffset";
import { ImageUri } from "@/types";
import { zodResolver } from "@hookform/resolvers/zod";
import { useNavigation } from "expo-router";
import { useEffect } from "react";
import { FormProvider, useForm } from "react-hook-form";
import { KeyboardAvoidingView, ScrollView, StyleSheet } from "react-native";
import z from "zod";
export default function PostWriteScreen() {
// ...
const { isKeyboardShown, keyboardVerticalOffsetValue } = useKeyboardOffset();
// ...
useEffect(() => {
navigation.setOptions({
headerRight: () => (
<Button
label="Save"
size="medium"
variant="standard"
onPress={postForm.handleSubmit(onSubmit)}
/>
),
});
});
// ...
return (
<FormProvider {...postForm}>
<KeyboardAvoidingView
behavior="padding"
keyboardVerticalOffset={keyboardVerticalOffsetValue}
enabled={isKeyboardShown}
style={{ flex: 1 }}
>
<ScrollView
style={styles.container}
contentContainerStyle={styles.contentContainer}
>
<TitleInput />
<DescriptionInput />
<DescriptionInput />
<DescriptionInput />
<DescriptionInput />
</ScrollView>
</KeyboardAvoidingView>
</FormProvider>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
contentContainer: {
flexGrow: 1,
padding: 16,
gap: 16,
},
});
import { useEffect, useState } from "react";
import { Keyboard } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
export default function useKeyboardOffset() {
const [isKeyboardShown, setIsKeyboardShown] = useState<boolean>(false);
const insets = useSafeAreaInsets();
const verticalInsets = insets.top + insets.bottom;
const keyboardVerticalOffsetValue = (Keyboard.metrics()?.height || 0) + verticalInsets + 50;
useEffect(() => {
const showSubscription = Keyboard.addListener("keyboardDidShow", () => {
setIsKeyboardShown(true);
});
const hideSubscription = Keyboard.addListener("keyboardDidHide", () => {
setIsKeyboardShown(false);
});
return () => {
showSubscription.remove();
hideSubscription.remove();
};
}, []);
return { isKeyboardShown, keyboardVerticalOffsetValue };
}
단순히 Keyboard 문서를 확인하니 event listener 부분이 있어 그걸 참고하여 metric().height 만큼 offset을 주고 비슷하게 동작은 하도록 작성했습니다. 추가적으로, 아랫 부분이 조금 짤려서 임의로 50을 추가했습니다.
이미 비슷한 질문이 올라 왔길래 '안드로이드 KeyboardAwareScrollView 이슈 수정 & 키보드 상태 커스텀 훅 만들기' 강의 확인하고 훅으로만 분리했는데 강의 중 상세 코드는 다르기도 하고 iOS 환경에서는 테스트를 할 수가 없어서 이런 식으로 짜도 되는지, 그리고 위에서 언급한 50에 해당하는 공간이 왜 필요한지 질문 드립니다.
답변 1
0
안녕하세요, 인프런 AI 인턴입니다. yeong님.
React Native 환경에서 키보드 관련 이슈는 매우 자주 접할 수 있는 문제 중 하나입니다. 특히, KeyboardAvoidingView
와 같은 컴포넌트를 사용하는 과정에서 안드로이드나 iOS 환경에 따라 동작이 다를 수 있습니다.
키보드 이벤트 리스너 활용:
isKeyboardShown
상태를 관리하고 있습니다. 이렇게 하여 폼이 제출될 때 키보드의 상태를 체크할 수 있습니다.키보드 높이 측정 및 Vertical Offset:
Keyboard.metrics()?.height
를 사용하여 키보드의 높이를 얻고 있습니다. 이 높이값은 키보드가 활성화될 때 얼마나 내용을 올려야 하는지를 결정짓는 데 중요한 요소입니다.50
의 임의 값을 추가하여 offset을 설정한 이유는, 키보드의 높이 외에 스크롤 시 약간의 여유 공간을 제공하기 위한 것입니다. 이는 사용자 경험을 향상시키기 위해 종종 사용되는 방식이며, 실제 디바이스 테스트를 통해 적절한 값을 조정하는 것이 좋습니다.KeyboardAvoidingView
의 유용성:
KeyboardAvoidingView
는 특히 ScrollView
와 함께 자주 사용되며, 키보드에 의해 입력 창이 가려지는 현상을 해결하는 데 도움이 됩니다.behavior
속성을 통해 키보드가 나타날 때 뷰가 어떻게 동작할지 (padding
, height
, position
)를 결정할 수 있습니다.제가 제공한 설명과 자료가 도움이 되기를 바라며, 위의 방법으로 문제가 해결되길 바랍니다. 추가적인 궁금증이 있으시면 언제든지 질문해 주세요.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.