我使用react-native-bottom-sheet来选择一个类别,当Amount输入具有autofocus
属性时,屏幕上会出现下面的表单。
最下面的一张纸出现在键盘后面,它没有按照我想要的捕捉点,它应该在屏幕的中间,但它总是稍微高于键盘。这种情况并不总是发生,像2/5尝试,而且只有当我第一次打开这个屏幕时。工作表应该只在我点击类别时打开,在进入屏幕时应该隐藏。我试着使用一些变量render
来检查底部的工作表是否需要渲染,所以我根本不渲染它,但我可以看到它只是闪烁了一秒钟。
这是我的底部表单组件。因为我想创建一个可重用的组件,所以我使用ref将打开底部表单的函数传递给父组件。
const TransactionBottomSheet: React.ForwardRefRenderFunction<refProps, Props> = (props, ref) => {
const { onSelect } = props;
const sheetRef = useRef<BottomSheet>(null);
const [data, setData] = useState<Transaction[]>(categoriesData);
const [selectedCategory, setSelectedCategory] = useState<Category | null>(null);
const openSheet = useCallback(() => {
sheetRef.current?.expand();
}, []);
const closeSheet = useCallback(() => {
sheetRef.current?.close();
}, []);
useImperativeHandle(ref, () => ({
openSheet: () => openSheet(),
}));
const setTypeData = (id: number) => {
const types = transactionCategories[id].types ?? [];
setData(Object.values(types));
};
const clearCategory = () => {
setData(categoriesData);
setSelectedCategory(null);
};
const onRowPress = (item: Transaction | Category) => {
if (!selectedCategory) {
setTypeData(item.id);
setSelectedCategory(item as Category);
} else {
onSelect(selectedCategory, item);
closeSheet();
}
};
const onClose = () => {
setData(categoriesData);
setSelectedCategory(null);
};
const renderItem = ({ item }: { item: Transaction | Category }) => (
<TransactionRowSelect item={item} hideIcon={!!selectedCategory} onPress={onRowPress} />
);
const renderBackdrop = useCallback(
(props) => <BottomSheetBackdrop {...props} disappearsOnIndex={-1} appearsOnIndex={0} />,
[]
);
return (
<BottomSheet
ref={sheetRef}
snapPoints={snapPoints}
enablePanDownToClose
index={-1}
onClose={onClose}
backdropComponent={renderBackdrop}
handleStyle={styles.handle}
>
<Label style={styles.title}>{"Pick category"}</Label>
{!!selectedCategory && (
<>
<TransactionRowSelect item={selectedCategory} onPress={clearCategory} />
<Separator />
</>
)}
<BottomSheetFlatList
data={data}
keyExtractor={(item) => `${item.id}`}
renderItem={renderItem}
/>
</BottomSheet>
);
};
const styles = StyleSheet.create({
title: {
textAlign: "center",
fontSize: 16,
fontWeight: "bold",
paddingBottom: 10,
backgroundColor: colors.grey3,
},
handle: {
backgroundColor: colors.grey3,
borderTopLeftRadius: 10,
borderTopRightRadius: 10,
},
});
export default React.forwardRef(TransactionBottomSheet);
这是添加交易屏幕
const TransactionForm: React.FC<Props> = ({ navigation }) => {
const [date, setDate] = useState(new Date());
const sheetRef = useRef<TransactionBottomSheetType>(null);
const [category, setCategory] = useState<Category | null>(null);
const [type, setType] = useState<Transaction | null>(null);
const [amount, setAmount] = useState("");
const [description, setDescription] = useState("");
const [tryCreateNewTransaction, { isLoading }] = useCreateNewTransactionMutation();
const onAdd = async () => {
Keyboard.dismiss();
try {
if (type && category) {
await tryCreateNewTransaction({
amount: Number(amount),
description,
date: formatIsoDate(date),
user_id: 1,
type_id: type.id,
category_id: category.id,
}).unwrap();
navigation.goBack();
}
} catch (error) {
Alert.alert("An error occurred while adding transaction", "Please try again");
}
};
const onSelectCategory = (category: Category, type: Transaction) => {
setCategory(category);
setType(type);
};
const setCategoryText = () => {
if (!category && !type) {
return "";
}
return `${category?.label}, ${type?.label}`;
};
const openSheet = () => {
if (sheetRef?.current) {
Keyboard.dismiss();
sheetRef?.current?.openSheet();
}
};
return (
<View style={styles.container}>
<DatePickerInput date={date} maximumDate={new Date()} onDateSelect={setDate} />
// This is just TextInput component with some custom style, here is the autofocus props
<LabelInput
value={amount}
placeholder='Amount'
onChangeText={setAmount}
keyboardType='decimal-pad'
style={styles.marginTop}
icon={<FontAwesome5 name='coins' size={24} color={colors.greenMint} />}
autoFocus
/>
{/* <InputErrorLabel text={errors.amount} isVisible={!!errors.amount} /> */}
<TouchableOpacity onPress={openSheet}>
<LabelInput
value={setCategoryText()}
icon={<MaterialIcons name='category' size={24} color={colors.greenMint} />}
disabled
placeholder='Category'
style={styles.marginTop}
inputStyle={styles.category}
/>
</TouchableOpacity>
<TextBox
placeholder='Transaction comment'
style={styles.marginTop}
numberOfLines={6}
maxLength={300}
value={description}
onChangeText={setDescription}
/>
<CustomButton title='Submit' onPress={onAdd} style={styles.marginTop} />
<AppActivityIndicator isLoading={isLoading} />
<TransactionBottomSheet ref={sheetRef} onSelect={onSelectCategory} />
</View>
);
};
export default TransactionForm;
const styles = StyleSheet.create({
container: {
flex: 1,
paddingHorizontal: 16,
paddingTop: 20,
},
marginTop: {
marginTop: 20,
},
category: {
color: colors.black,
},
});
2条答案
按热度按时间ulydmbyx1#
找到了一个解决这个问题的方法,它看起来像是与键盘和expo有关。我注意到当键盘被显示或关闭时,有一个白色的背景在它后面显示了一瞬间。我通过将这个添加到
app.json
来修复这个问题这也解决了键盘和底板的问题。没有看到它出现了。
zc0qhyus2#
听键盘
show/hide
的声音,然后对底部表单做任何你想做的事情。例如,这里我改变了底部表单的捕捉点。