You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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图标仍无效。

效果截图

  • 预期效果:汉堡图标正常显示的导航栏
  • 异常效果:多数iPhone设备左上角汉堡图标缺失

复现仓库

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 01:45:57