最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

memory - Problem with Viro - React in combination with Expo. Cannot Exit out of the Screen where viroReact is setup - Stack Over

programmeradmin2浏览0评论

I have an app that needs the functionality to scan icons out of a database and links to a new screen. The "scanning" works perfect but I can't navigate back to the cameraScreen once i exited the screen. Right now I am using router.push("/") to exit the screen but somehow i cant reenter the screen once i got out of it.

Here are the scripts:

import React, { useState, useEffect, useRef } from "react";
import {
  ViroARScene,
  ViroARSceneNavigator,
  ViroARTrackingTargets,
  ViroARImageMarker,
} from "@viro-community/react-viro";
import { Image, View, Text, TouchableOpacity } from "react-native";
import { router } from "expo-router";
import { databases, appwriteConfig } from "../lib/appwriteConfig";

type Icon = {
  name: string;
  source: string;
  physicalWidth: number;
  videos: string;
  recipes: string;
  icon_type: "video" | "recipe" | "timer";
};

type TrackingTarget = {
  source: { uri: string };
  orientation: string;
  physicalWidth: number;
};

const CameraScreen = () => {
  const [iconsArray, setIconsArray] = useState<Icon[]>([]);
  const [loading, setLoading] = useState(true);
  const [arNavigator, setArNavigator] = useState(true);
  const arNavigatorRef = useRef<any>(null);

  useEffect(() => {
    const fetchIcons = async () => {
      try {
        const response = await databases.listDocuments(
          appwriteConfig.databaseId,
          appwriteConfig.iconsCollectionId
        );

        const icons = response.documents.map((icon: any) => {
          let videoId = "";
          let recipeId = "";

          if (Array.isArray(icon.videos) && icon.videos.length > 0) {
            videoId = icon.videos[0]?.$id || "";
          } else if (typeof icon.videos === "object" && icon.videos?.$id) {
            videoId = icon.videos.$id;
          } else if (typeof icon.videos === "string") {
            videoId = icon.videos;
          }

          if (typeof icon.recipes === "object" && icon.recipes?.$id) {
            recipeId = icon.recipes.$id;
          } else if (typeof icon.recipes === "string") {
            recipeId = icon.recipes;
          }

          return {
            name: icon.name,
            source: icon.image,
            physicalWidth: 0.1,
            videos: videoId,
            recipes: recipeId,
            icon_type: icon.icon_type || "video",
          };
        });

        setIconsArray(icons);
      } catch (error) {
        console.error("Error fetching icons:", error);
      } finally {
        setLoading(false);
      }
    };

    fetchIcons();

    return () => {
      if (arNavigatorRef.current) {
        arNavigatorRef.current.reset();
        arNavigatorRef.current = null;
      }
      setArNavigator(false);
    };
  }, []);

  useEffect(() => {
    if (iconsArray.length > 0) {
      const trackingTargets: Record<string, TrackingTarget> = {};
      iconsArray.forEach((icon) => {
        trackingTargets[icon.name] = {
          source: { uri: icon.source },
          orientation: "Up",
          physicalWidth: icon.physicalWidth,
        };
      });
      ViroARTrackingTargets.createTargets(trackingTargets);
    }
  }, [iconsArray]);

  const handleAnchorFound = (iconName: string) => {
    const detectedIcon = iconsArray.find((icon) => icon.name === iconName);

    if (!detectedIcon) {
      console.warn(`No icon found for name: ${iconName}`);
      return;
    }

    switch (detectedIcon.icon_type) {
      case "video":
        if (detectedIcon.videos) {
          router.push(`./manager/videoManager?videoId=${detectedIcon.videos}`);
        } else {
          console.warn(`No video ID found for icon: ${iconName}`);
        }
        break;

      case "recipe":
        if (detectedIcon.recipes) {
          router.push(`./cookingInformationScreen?id=${detectedIcon.recipes}`);
        } else {
          console.warn(`No recipe ID found for icon: ${iconName}`);
        }
        break;

      case "timer":
        console.log("Timer functionality not implemented yet.");
        break;

      default:
        console.warn(`Unknown icon type: ${detectedIcon.icon_type}`);
        break;
    }
  };

  const handleAnchorLost = (iconName: string) => {
    console.log(`Lost: ${iconName}`);
  };

  const ARScene = () => (
    <ViroARScene>
      {iconsArray.map((icon) => (
        <ViroARImageMarker
          key={icon.name}
          target={icon.name}
          onAnchorFound={() => handleAnchorFound(icon.name)}
          onAnchorRemoved={() => handleAnchorLost(icon.name)}
        />
      ))}
    </ViroARScene>
  );

  return (
    <View className="flex-1 relative">
      <TouchableOpacity onPress={() => router.push("/")} className="flex-row items-center">
        <Text className="text-lg font-semibold text-black">← Zurück</Text>
      </TouchableOpacity>
      {loading ? (
        <View className="flex-1 justify-center items-center">
          <Text className="text-white">Loading icons...</Text>
        </View>
      ) : (
        arNavigator && (
          <ViroARSceneNavigator
            ref={arNavigatorRef}
            autofocus={true}
            initialScene={{ scene: ARScene }}
            className="flex-1"
          />
        )
      )}
      <Image
        source={require("../images/ScanningOverlay.png")}
        className="absolute inset-0"
        style={{
          position: "absolute",
          top: "20%",
          left: "20%",
          width: 350,
          height: 350,
          transform: [{ translateX: -55 }, { translateY: 10 }],
        }}
      />
    </View>
  );
};

export default CameraScreen;

And the Button from which i go back into the screen:


import React from "react";
import { TouchableOpacity, Text } from "react-native";
import { router } from "expo-router";

export default function CameraButton() {
  return (
    <TouchableOpacity 
        className="absolute bottom-8 self-center bg-gray-300 rounded-full p-10 z-10"
        onPress={() => router.replace("/cameraScreen")} // Use replace instead of push
    >
        <Text className="text-gray-600 text-2xl">

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论