Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Component unmounts when going to next screen #224

Open
adaryabegi opened this issue Jan 16, 2022 · 6 comments
Open

Component unmounts when going to next screen #224

adaryabegi opened this issue Jan 16, 2022 · 6 comments

Comments

@adaryabegi
Copy link

adaryabegi commented Jan 16, 2022

Hey guys. I am struggling here on an issue I can't figure out. So basically what I have, is 1 image that I want to transition into a full screen Image on a new screen. I followed the docs and its no big hack, just really simple, but as soon as the Image is almost on the new screen, it unmounts or something and then shows again.

Showcase of the problem:

Bildschirmaufnahme.2022-01-16.um.22.58.16.mov

I have a Navigator:

import { createSharedElementStackNavigator } from "react-navigation-shared-element"
import ChatImgGallery from "./ChatImgGallery"
import OneToOneScreen from "./OneToOneScreen"

const iosTransitionSpec = {
  animation: "spring",
  config: {
    stiffness: 1000,
    damping: 500,
    mass: 3,
    overshootClamping: true,
    restDisplacementThreshold: 10,
    restSpeedThreshold: 10,
  },
}

const options = {
  cardStyleInterpolator: ({ current: { progress } }) => {
    return { cardStyle: { opacity: progress } }
  },
  gestureEnabled: false,
  // ...TransitionPresets.ModalSlideFromBottomIOS,
  transitionSpec: {
    open: iosTransitionSpec,
    close: iosTransitionSpec,
  },
}

const ChatStack = createSharedElementStackNavigator()

export default function ChatNavigator() {
  return (
    <ChatStack.Navigator
      screenOptions={{ headerShown: false, useNativeDriver: true }}
    >
      <ChatStack.Screen name="OneToOneChat" component={OneToOneScreen} />
      <ChatStack.Screen
        name="ChatImgGallery"
        component={ChatImgGallery}
        sharedElements={(route, otherRoute, showing) => {
          const { item, uri } = route.params
          return [`item.${uri}.photo`]
        }}
        options={() => options}
      />
    </ChatStack.Navigator>
  )
}

This is a Component called "NormalMessage" inside the "OneToOneScreen":

{message?.files?.length > 0
          ? message?.files.map((file, index) => (
              <TouchableOpacity
                style={{
                  width: MAX_IMG_WIDTH,
                  height: MAX_IMG_WIDTH,
                  borderRadius: 19,
                  marginTop:
                    index <= message.files.length - 1 && index !== 0 ? 10 : 0,
                }}
                onPress={() =>
                  navigate("ChatImgGallery", {
                    item: message,
                    file: index,
                    uri: file.location,
                  })
                }
              >
                <SharedElement id={`item.${file.location}.photo`}>
                  <Image
                    source={{ uri: file.location }}
                    style={{
                      width: "100%",
                      height: "100%",
                      borderRadius: 19,
                    }}
                  />
                </SharedElement>
              </TouchableOpacity>
            ))
          : null}

This is the component "ChatImgGallery":

import React from "react"
import {
  View,
  StyleSheet,
  Image,
  TouchableOpacity,
  Dimensions,
} from "react-native"
import { SharedElement } from "react-navigation-shared-element"
import { useSafeAreaInsets } from "react-native-safe-area-context"
import { useNavigation } from "@react-navigation/native"
import { Ionicons } from "@expo/vector-icons"

const { height, width } = Dimensions.get("window")

export default function ChatImgGallery({ route }) {
  const { bottom, top } = useSafeAreaInsets()
  const { item, uri } = route.params
  const { goBack } = useNavigation()

  return (
    <View style={styles.container}>
      <View style={[styles.topView, { paddingTop: top + 10 }]}>
        <TouchableOpacity onPress={goBack}>
          <Ionicons name="close-outline" size={24} color="white" />
        </TouchableOpacity>
      </View>
      <SharedElement id={`item.${uri}.photo`}>
        <Image
          source={{ uri }}
          style={{ width, height }}
          resizeMode="cover"
          load
        />
      </SharedElement>
    </View>
  )
}

const styles = StyleSheet.create({
  container: {
    ...StyleSheet.absoluteFillObject,
  },
  imgView: {
    ...StyleSheet.absoluteFillObject,
  },
  topView: {
    width: "100%",
    backgroundColor: "rgba(0,0,0,0.6)",
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    paddingHorizontal: 20,
    position: "absolute",
    left: 0,
    top: 0,
    zIndex: 2,
  },
})

Important package versions:

    "expo": "~44.0.0",
    "react": "17.0.1",
    "react-dom": "17.0.1",
    "react-native": "0.64.3",
    "@react-navigation/native": "5.x.x",
    "@react-navigation/stack": "5.x.x",
    "react-native-screens": "~3.0.0",
    "react-native-shared-element": "^0.8.3",
    "react-navigation": "^4.4.4",
    "react-navigation-shared-element": "^3.1.3",
    "react-navigation-stack": "^2.10.4",
@dirmich
Copy link

dirmich commented May 26, 2022

add cardStyle: {backgroundColor: 'transparent'} to options

@Engazan
Copy link

Engazan commented Jul 10, 2022

for me this helper add this styles to your Screen opntions

                   cardStyle: {
                        backgroundColor: 'transparent'
                    },
                    cardStyleInterpolator: ({current}) => {
                        return {
                            cardStyle: {
                                opacity: current.progress,
                                backgroundColor: 'transparent'
                            }
                        }
                    }

example from my code

              <Stack.Screen
                name="TicketDetailScreen"
                component={TicketDetailScreen}
                options={{
                    gestureEnabled: false,
                    transitionSpec: {
                        open: {animation: 'timing', config: {duration: 300}},
                        close: {animation: 'timing', config: {duration: 300}}
                    },
                    cardStyle: {
                        backgroundColor: 'transparent'
                    },
                    cardStyleInterpolator: ({current}) => {
                        return {
                            cardStyle: {
                                opacity: current.progress,
                                backgroundColor: 'transparent'
                            }
                        }
                    }
                }}
            />

@pouyarezvani
Copy link

@dirmich cardStyle: {backgroundColor: 'transparent'} didnt fix it for me.
Any other ideas?
What is even the point of transparency?
this makes the page see-through. In that case, I would have to assign a background color to the scroll view, and it's not a good UI behavior.
My image still flickers just like the original comment on this post.

@adaryabegi Did you find a solution?

@pouyarezvani
Copy link

pouyarezvani commented Mar 19, 2023

I was able to reproduce it in the video shared below.
The second image is the one that flickers after it navigates. Both Images are loaded from the Cloud with URI
Could it have to do with the quality of the image? not sure.
@IjzerenHein any ideas?

RPReplay_Final1679185209.MP4

@IjzerenHein
Copy link
Owner

@pouyarezvani I think this has to do with caching and the second image being larger in size. Could you log out the sizes of both images? Also, is it always the second image in the list that produces the problem, or does it happen to particular image-url's and not to others?

@VictorioMolina
Copy link

VictorioMolina commented Jul 17, 2023

@IjzerenHein Same here. In my case, images loaded from cache too, with same dimensions (aprox) and a size of 100KB.

I am using expo-image (most recent version).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants