Expo Drawer组件在部分iPhone生产环境中图标不显示求助
Expo Router抽屉导航汉堡图标在iOS生产包中视觉消失问题
我们基于React Expo、Expo File Router和TypeScript开发,使用Expo SDK 51(搭配React Native 0.75),通过expo-router/drawer的Drawer组件实现抽屉导航。本地开发构建(Expo Go模拟器及物理设备)中抽屉导航正常渲染且功能正常,但使用EAS Build构建生产包后,除iPhone 11外的其他iPhone设备上,抽屉头部的汉堡图标仅视觉消失,功能仍可用(Android设备无此问题)。我们使用Node.js 20.15.0,即使创建最小复现示例(仅默认Expo Router依赖),该问题仍存在。
TLDR:生产环境中,汉堡导航栏在Android和iPhone 11上正常显示,但在iPhone X、12、15 Pro等设备上仅功能存在,图标视觉消失;尝试设置fallback图标仍无效。
效果截图
- 预期效果:

- 异常效果:

复现仓库
github.com/AntonioRoye/drawer-header-test
最小复现代码
package.json
{ "name": "stickersmash", "main": "expo-router/entry", "version": "1.0.0", "scripts": { "start": "expo start", "reset-project": "node ./scripts/reset-project.js", "android": "expo run:android", "ios": "expo run:ios", "web": "expo start --web", "test": "jest --watchAll", "lint": "expo lint" }, "jest": { "preset": "jest-expo" }, "dependencies": { "@expo/vector-icons": "^14.0.2", "@react-navigation/drawer": "^6.7.2", "@react-navigation/native": "^6.0.2", "expo": "~51.0.28", "expo-constants": "~16.0.2", "expo-font": "~12.0.9", "expo-linking": "~6.3.1", "expo-router": "~3.5.23", "expo-splash-screen": "~0.27.5", "expo-status-bar": "~1.12.1", "expo-system-ui": "~3.0.7", "expo-web-browser": "~13.0.3", "react": "18.2.0", "react-dom": "18.2.0", "react-native": "0.74.5", "react-native-gesture-handler": "~2.16.1", "react-native-reanimated": "~3.10.1", "react-native-safe-area-context": "4.10.5", "react-native-screens": "3.31.1", "react-native-web": "~0.19.10", "@react-native-picker/picker": "2.7.5", "expo-updates": "~0.25.27" }, "devDependencies": { "@babel/core": "^7.20.0", "@types/jest": "^29.5.12", "@types/react": "~18.2.45", "@types/react-test-renderer": "^18.0.7", "jest": "^29.2.1", "jest-expo": "~51.0.3", "react-test-renderer": "18.2.0", "typescript": "~5.3.3" }, "private": true }
eas.json
{ "cli": { "version": ">= 10.2.3", "appVersionSource": "remote" }, "build": { "development": { "developmentClient": true, "distribution": "internal", "channel": "development" }, "ios-simulator": { "extends": "development", "ios": { "simulator": true } }, "preview": { "distribution": "internal", "channel": "preview" }, "production": { "autoIncrement": true, "channel": "production" } }, "submit": { "production": { "android": { "serviceAccountKeyPath": "****", "track": "internal", "releaseStatus": "draft" }, "ios": { "appleId": "****", "ascAppId": "****", "appleTeamId": "****", "bundleIdentifier": "****" } } } }
VehiclePage.tsx
import React, { useState } from "react"; import { View, Text, TouchableOpacity, StyleSheet, ScrollView } from "react-native"; import { Picker } from "@react-native-picker/picker"; const VehiclePage = () => { const [activeTab, setActiveTab] = useState<string>("Vehicle Info"); const [vehicleType, setVehicleType] = useState<string>("Passenger Vehicle"); return ( <View style={styles.container}> <View style={styles.header}> <Text style={styles.title}>Vehicle Page</Text> </View> <ScrollView contentContainerStyle={styles.scrollContainer}> {/* Tab Buttons */} <View style={styles.tabContainer}> <TouchableOpacity style={[ styles.tabButton, activeTab === "Vehicle Info" && styles.activeTabButton, ]} onPress={() => setActiveTab("Vehicle Info")} > <Text style={[ styles.tabButtonText, activeTab === "Vehicle Info" && styles.activeTabButtonText, ]} > Vehicle Info </Text> </TouchableOpacity> <TouchableOpacity style={[ styles.tabButton, activeTab === "Odometer" && styles.activeTabButton, ]} onPress={() => setActiveTab("Odometer")} > <Text style={[ styles.tabButtonText, activeTab === "Odometer" && styles.activeTabButtonText, ]} > Odometer </Text> </TouchableOpacity> </View> {/* Content based on tab selection */} {activeTab === "Vehicle Info" ? ( <View style={styles.contentContainer}> <Text style={styles.label}>Vehicle Type</Text> <View style={styles.pickerContainer}> <Picker selectedValue={vehicleType} onValueChange={(itemValue) => setVehicleType(itemValue)} style={styles.picker} > <Picker.Item label="Select Vehicle" value="" /> <Picker.Item label="Motor Vehicle" value="Motor Vehicle" /> <Picker.Item label="Passenger Vehicle" value="Passenger Vehicle" /> </Picker> </View> </View> ) : ( <View style={styles.contentContainer}> <Text style={styles.label}>Odometer Tab Content</Text> </View> )} </ScrollView> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#fff", }, scrollContainer: { flexGrow: 1, width: "100%", }, header: { padding: 20, alignItems: "center", backgroundColor: "#0078A0", }, title: { fontSize: 24, color: "white", fontWeight: "bold", }, tabContainer: { flexDirection: "row", justifyContent: "space-around", marginVertical: 20, }, tabButton: { padding: 10, backgroundColor: "#f0f0f0", borderRadius: 5, }, activeTabButton: { backgroundColor: "#0078A0", }, tabButtonText: { fontSize: 16, color: "#000", }, activeTabButtonText: { color: "white", fontWeight: "bold", }, contentContainer: { padding: 20, }, label: { fontSize: 16, marginBottom: 10, }, pickerContainer: { borderWidth: 1, borderRadius: 5, borderColor: "#ddd", padding: 5, }, picker: { width: "100%", }, }); export default VehiclePage;
index.tsx
import { Text, View } from "react-native"; export default function Index() { return ( <View style={{ flex: 1, justifyContent: "center", alignItems: "center", }} > <Text>Edit app/index.tsx to edit this screen.</Text> </View> ); }
_layout.tsx
import 'react-native-gesture-handler'; import 'react-native-reanimated'; import React from "react"; import { StyleSheet} from "react-native"; import {Drawer} from "expo-router/drawer"; import { GestureHandlerRootView } from "react-native-gesture-handler"; export default function App() { return ( <GestureHandlerRootView style={{ flex: 1 }}> <Drawer screenOptions={{ headerShown: true, drawerStyle: { backgroundColor: "#404040", }, drawerLabelStyle: { color: "white" }, }} > <Drawer.Screen name="index" options={{ drawerLabel: "Index", headerTitle: () => null, headerTitleStyle: { fontWeight: "bold", } }} /> <Drawer.Screen name="vehicle" options={{ drawerLabel: "Vehicle", title: "Vehicle", headerTitleStyle: { fontWeight: "bold", }, }} /> </Drawer> </GestureHandlerRootView> ); } const styles = StyleSheet.create({ drawerHeader: { height: 150, alignItems: "center", justifyContent: "center", }, drawerIcon: { width: 250, height: 67, }, loadingContainer: { flex: 1, justifyContent: "center", alignItems: "center", backgroundColor: "#f2f2f2", }, });
内容的提问来源于stack exchange,提问作者Santiago Vargas
相关产品推荐
相关产品推荐

