일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 알고리즘
- git
- LinkSnap
- cpu
- 백준
- nodejs
- html/css/js
- 국비지원
- 국비지원취업
- 호이스팅
- 프론트엔드개발자
- DFS
- KAKAO
- 컴퓨터과학
- 야놀자
- computerscience
- github
- 패스트캠퍼스
- 그리디
- 너비우선탐색
- 코테
- 부트캠프
- Javascript
- 코딩테스트
- CS
- 자바스크립트
- 컴퓨터공학
- js
- CSS
- BFS
- Today
- Total
My Boundary As Much As I Experienced
RN) 모바일 키보드 조작에 대한 모든 것 (TextInput, AvoidingKeyboardView) 본문
RN) 모바일 키보드 조작에 대한 모든 것 (TextInput, AvoidingKeyboardView)
Bumang 2024. 8. 21. 00:11이번에 회사에서 RN으로 초기앱을 세팅부터 다시 해볼 수 있는 기회가 생겼다.
돈 되보이는 것들은 모두 한 번 만들어보자는 싸장님의 방향성 덕분에 앞으로도 초기세팅을 해볼 일이 많아질거 같다..
RN은 React와 거의 비슷한 구조로 사용할 수 있지만 가장 차이나는 부분은 input의 활용 부분인 거 같다.
이번에 초기세팅하면서 배운 부분들을 정리해보려 한다.
1. TextInput
웹에서 쓰는 input은 RN에서 TextInput 컴포넌트로 사용할 수 있다.
웹과 구별되는 속성:
editable:
- 사용자 입력을 받을 수 있는지 없는지 여부를 설정한다. (boolean)
type:
- 텍스트에 입력되는 정보들의 타입을 결정한다. 기본은 "text" ("text" | "number" | "password")
keyboardType:
- 텍스트인풋을 선택했을 때 올라오는 키보드를 ("default" | "numeric" | "email-address")
ReturnKeyType:
- 노출된 키보드의 '다음' 버튼의 텍스트를 결정한다. ("next" | "done" | "go" | "send" | "search")
onChangeText:
- 웹에서는 onChange속성을 사용하겠지만, 여기선 onChangeText라는 속성밖에 사용하지 못한다. 또한 event를 받지 않고 실제 텍스트string를 패러미터로 받는다. ( (arg: string) => void; )
onSubmitEditing?:
- 수정을 완료하고 제출할 때 어떤 액션을 취해줄지 결정할 수 있다. api호출을 발생시킬수도 있고 다음 인풋으로 보낼수도 있다. 다음 인풋으로 보내려면 ref들을 적절히 이용해줘야 한다. 다음 input 선택하는 방법은 추후 포스팅으로 올리겠다. (cb)
blurOnSubmit:
- 제출 후 키보드가 내려가는지 안 내려가는지 여부를 결정한다.
나는 사용하기 편하게 customTextInput을 만들어 스타일과여러 속성들을 적용할 수 있게 만들었다.
(에러 시 인풋 아래 에러 문구 넣는 것도 추가할 예정이다.)
import React, { forwardRef, useState } from "react";
import { TextInput, StyleSheet, StyleProp } from "react-native";
import { theme } from "theme";
interface TextInputProps {
type?: "text" | "number" | "password";
keyboardType?: "default" | "numeric" | "email-address";
editable?: boolean;
placeholder?: string;
secureTextEntry?: boolean;
value?: string;
onChangeText: (...arg: any[]) => void;
style?: StyleProp<any>;
borderColor?: string;
returnKeyType?: "next" | "done" | "go" | "send" | "search";
onSubmitEditing?: () => void;
blurOnSubmit?: boolean;
}
const CustomTextInput = forwardRef<TextInput, TextInputProps>(
(
{
type = "text", // 'text', 'number', 'password'
keyboardType = "default", // 'default', 'numeric', 'email-address', etc.
returnKeyType = "done",
editable = true,
placeholder = "",
value,
onChangeText,
secureTextEntry = false,
style,
borderColor = theme.colors.gray.DEFAULT,
onSubmitEditing,
blurOnSubmit = true,
}: TextInputProps,
ref
) => {
const [isFocused, setIsFocus] = useState(false);
const styles = StyleSheet.create({
input: {
height: 48,
borderColor: isFocused ? theme.colors.orange.DEFAULT : borderColor,
borderBottomWidth: isFocused ? 2 : 1,
padding: 10,
marginVertical: 10,
width: "100%",
// backgroundColor: "white",
// borderRadius: 8,
fontSize: 16,
},
});
return (
<TextInput
onFocus={() => setIsFocus(true)}
onBlur={() => setIsFocus(false)}
style={[styles.input, style]}
keyboardType={keyboardType}
placeholder={placeholder}
value={value}
onChangeText={onChangeText}
secureTextEntry={type === "password" ? true : secureTextEntry}
editable={editable}
returnKeyType={returnKeyType}
onSubmitEditing={onSubmitEditing}
blurOnSubmit={blurOnSubmit}
ref={ref}
/>
);
}
);
export default CustomTextInput;
2. KeyboardAvoidingView
키보드가 올라왔을 때 컨텐츠를 가리는 것을 방지하는 View이다.
아래 튜토리얼을 참고하는게 직관적으로 이해하기 좋을 것 같다.
https://www.youtube.com/watch?v=UcJyQ5MOoJo
난 처음에 KeyboardAvoidingView로 전체 페이지를 감쌌었는데 좋은 방법은 아니었다.
키보드가 올라갔을 때 전체페이지가 그대로 키보드 영역을 의식하에 Y축으로 조금씩 이동해야되는데
키보드가 나타날 때 페이지 전체가 움직일 수 있으며, 이로 인해 불필요한 영역까지 이동하게 될 수 있다.
특히, 비입력 요소가 많은 페이지에서는 사용자가 입력 필드가 아닌 다른 곳을 보고 있을 때
UI가 의도치 않게 이동할 수 있기 때문에 조심해야된다.
정말 키보드에 가리지 말아야할 일부 컴포넌트에만 써줘야 할 것 같다.
하여튼 나는 아래처럼 KeyboardAwareView라는 컴포넌트를 만들었다.
TouchableWithoutFeedback, SafeAreaView, KeyboardAvoidingView를 조합하여
키보드 영역 외를 누르면 키보드가 내려가는 컴포넌트를 만들어서 재사용하였다.
import { SafeAreaView } from "react-native-safe-area-context";
import {
Keyboard,
KeyboardAvoidingView,
Platform,
StyleProp,
TouchableWithoutFeedback,
} from "react-native";
interface KeyboardAwareProps {
style?: StyleProp<any>;
children: React.ReactNode;
}
const KeyboardAwareView = ({ children, style }: KeyboardAwareProps) => {
return (
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
<SafeAreaView style={style}>
<KeyboardAvoidingView //
behavior={Platform.OS === "ios" ? "padding" : "height"}
// keyboardVerticalOffset={300}
>
{children}
</KeyboardAvoidingView>
</SafeAreaView>
</TouchableWithoutFeedback>
);
};
export default KeyboardAwareView;
keyboardVerticalOffset:
키보드가 올라와서 어떤 요소를 가리는 것을 방지한다.
이걸 사용하면 아래처럼 키보드가 올라올 때 인풋창이 가리지 않고
키보드 위에 달려서(?) 잘 올라오도록 해줄 수 있다.
보통 안드로이드인 경우 굳이 해줄 필요 없고 iOS인 경우 100px 정도를 추가적으로 들어올려주면 된다고 한다.
iOS에선 왜 100px을 더 들어올려줘야 제대로 올라가냐고? 나도 몰라 얘네가 이렇게 구현해놨음..
경험적으로 keyboardVerticalOffset을 0으로 하면
iOS에선 해당 컴포넌트의 top부분이 키보드의 top부분과 맞닿아 가려지게 된다.
즉, 안드에서는 키보드 높이만큼 깔끔히 타겟 컴포넌트가 올라가는데, iOS는 좀 더 들어올려줘야 자연스러운 편.
알아서 offset값을 조절해서 원하는 View를 만들어라.
const TypingComponent = () => {
return (
<KeyboardAvoidingView
style={styles.container}
behavior={Platform.OS === "ios" ? "padding" : "height"}
keyboardVerticalOffset={Platform.OS === "ios" ? 80 : 0}
<View style={styles.inputContainer}>
<TextInput
placeholder="메시지를 입력하세요..."
style={styles.textInput}
/>
<Button
title="전송"
onPress={() => {
/* 메시지 전송 로직 */
}}
/>
</View>
</KeyboardAvoidingView>
);
};
'FrontEnd > React Native' 카테고리의 다른 글
RN) 바텀네비게이션에 바텀시트가 나오게 하는 버튼 만들기(Tab.Navigator) (0) | 2024.09.02 |
---|---|
RN) 맨날 하는 고민... 헤더와 스크린 간의 데이터 전달을 어떻게 할까? (navigation.setOptions) (0) | 2024.08.22 |
RN) 리액트 네비게이션 - 스크린 이동 총정리 (navigation객체와 훅, useNavigate) (0) | 2024.08.17 |
RN) 초기 앱 라우터 구조 짜기 (Stack, BottomTab) (0) | 2024.08.14 |
리액트 네이티브 막간 팁 (시뮬레이터 기기 바꾸는 법, Flipper 사용 중단하기) (0) | 2024.06.23 |