我在使用 SafeAreaView、KeyboardAvoidingView 和 ScrollView 时遇到 iOS 屏幕底部空白过多的问题。该布局在 Android 上运行良好,但在 iOS 上,内容下方有一个不需要的空白区域。
这是我当前对该组件的实现:
import React from "react";
import { SafeAreaView } from "react-native-safe-area-context";
import {
ScrollView,
KeyboardAvoidingView,
RefreshControl,
Platform,
} from "react-native";
import { StatusBar } from "expo-status-bar";
const MainView = ({
style,
children,
fixedHeader,
loading,
hasRefresh = false,
refreshing = false,
onRefresh,
onScroll,
needScrollView = true,
needTopEdge = true,
theme,
insets,
}) => {
return (
<SafeAreaView
style={[
styles.safeAreaView,
style,
{ paddingBottom: insets.bottom, marginBottom: 0 }, // Adjusting padding
]}
edges={
needTopEdge ? ["bottom", "left", "right", "top"] : ["bottom", "left", "right"]
}
>
{fixedHeader}
<KeyboardAvoidingView
style={{ flex: 1 }}
behavior={Platform.OS === "ios" ? "padding" : undefined}
keyboardVerticalOffset={insets.top + 10} // Setting offset
>
{needScrollView ? (
<ScrollView
onScroll={onScroll}
automaticallyAdjustKeyboardInsets={true}
contentContainerStyle={[
styles.scrollViewContent,
{ paddingBottom: insets.bottom }, // Adding bottom padding
]}
showsVerticalScrollIndicator={false}
refreshControl={
hasRefresh ? (
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
) : undefined
}
>
{loading ? <ThemedActiveIndicator /> : children}
</ScrollView>
) : (
<>{loading ? <ThemedActiveIndicator /> : children}</>
)}
</KeyboardAvoidingView>
<StatusBar
style={theme === "dark" ? "light" : "dark"}
backgroundColor={"black"}
/>
</SafeAreaView>
);
};
const styles = {
safeAreaView: {
flex: 1,
backgroundColor: "white",
},
scrollViewContent: {
flexGrow: 1,
paddingBottom: 20, // Adding padding
},
};
export default MainView;
#此代码也遇到相同的空白问题
import { SafeAreaView, useSafeAreaInsets } from "react-native-safe-area-context";
import { StatusBar } from "expo-status-bar";
import React, { ReactNode } from "react";
import { ScrollView, StyleSheet, RefreshControl, NativeSyntheticEvent, NativeScrollEvent } from "react-native";
import { StyleProps } from "react-native-reanimated";
import { ThemedView } from "@/components/ThemedView";
import { useGlobalContext } from "@/context/GlobalProvider";
import ThemedActiveIndicator from "../themedActiveIndicator/ThemedActiveIndicator";
interface Props {
children: React.ReactNode;
style?: StyleProps;
needTopEdge?: boolean;
hasRefresh?: boolean;
refreshing?: boolean;
onRefresh?: () => void;
fixedHeader?: ReactNode;
onScroll?: (e: NativeSyntheticEvent<NativeScrollEvent>) => void;
loading?:boolean;
needScrollView?:boolean;
addBottomMargin?:boolean;
}
const MainView = ({
children,
style,
needTopEdge = false,
hasRefresh = false,
refreshing = false,
loading=false,
fixedHeader,
onScroll,
onRefresh = () => {},
needScrollView=true,
addBottomMargin=false
}: Props) => {
const { theme } = useGlobalContext();
const inserts = useSafeAreaInsets()
return (
<ThemedView style={{ height: "100%" }}>
<SafeAreaView
style={[
styles.safeAreaView,
style,
addBottomMargin ? { marginBottom: inserts.top +60 } : {},
]}
edges={
needTopEdge
? ["bottom", "left", "right", "top"]
: ["bottom", "left", "right"]
}
>
{fixedHeader}
{needScrollView ? (
<ScrollView
onScroll={onScroll}
automaticallyAdjustKeyboardInsets={true}
contentContainerStyle={styles.scrollViewContent}
showsVerticalScrollIndicator={false}
refreshControl={
hasRefresh ? (
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
) : undefined
}
>
{loading ? <ThemedActiveIndicator /> : children}
</ScrollView>
) : (
<>{loading ? <ThemedActiveIndicator /> : children}</>
)}
<StatusBar
style={theme == "dark" ? "light" : "dark"}
backgroundColor={"black"}
/>
</SafeAreaView>
</ThemedView>
);
};
const styles = StyleSheet.create({
safeAreaView: { flex: 1, padding: 0, margin: 0 },
keyboardAvoidingView: { flex: 1 },
scrollViewContent: { flexGrow: 1 },
});
export default React.memo(MainView);
在 iOS 上:
到目前为止我尝试过的:
keyboardVerticalOffset
中调整 KeyboardAvoidingView
。paddingBottom
的 contentContainerStyle
中添加/删除 ScrollView
。flexGrow: 1
。console.log(insets.bottom)
进行调试,以确保正确计算安全区域插入。SafeAreaView
、KeyboardAvoidingView
和 ScrollView
来避免此问题?任何帮助或见解将不胜感激! 😊
这是针对您的问题的解决方案,基于平台应用填充。
const styles = {
safeAreaView: {
flex: 1,
backgroundColor: "white",
},
scrollViewContent: {
flexGrow: 1, //removed paddingBottom from here.
},
};
像这样添加平台检查:
<ScrollView
onScroll={onScroll}
automaticallyAdjustKeyboardInsets={true}
contentContainerStyle={[
styles.scrollViewContent,
{ paddingBottom: Platform.OS === 'android' ? 20 : insets.bottom}, // padding according to OS.
]}
showsVerticalScrollIndicator={false}
refreshControl={
hasRefresh ? (
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
) : undefined
}
>