Can't adjust when overlay label will appear on Android
mickaelcornelli opened this issue · comments
Hi,
First of all , thanks a lot for this library, you save me a lot of time to create my tinder like swap.
Let's talk about where i'm stuck. I've created a swiper with left overlay & right overlay (to accept & decline offer)
When I swipe on the left & right side on IOS there is no problem (check screen below) but on android there is no way to trigger faster the overlay. I've try to modify inputOverlayLabelsOpacityRangeX overlayOpacityHorizontalThreshold
. This works well on IOS but do not works on android.
I've also check a similar issue on this link :
#267
It helps me to fix my ios version but now still stuck on android.
I've try to modify inputoverlaylabel with separating the Platform.os ios/android with different value without any sucess.
I'm running the app with Expo 44 and React native 0.64.3
Video of IOS Swipe :
https://user-images.githubusercontent.com/73282517/179967284-fe16a9ae-2c38-4149-8060-9a0cf1deeda6.mp4
Video of Android Swipe :
https://user-images.githubusercontent.com/73282517/179967277-deb27327-d3e0-4e60-b6b9-1b7d7ce070c4.mp4
Thanks for any advice ;)
Code :
import { View, Text, Platform, StyleSheet, ImageBackground, Image, TouchableOpacity, Dimensions } from 'react-native'
import React, { useRef } from 'react'
import Swiper from "react-native-deck-swiper";
import { LinearGradient } from "expo-linear-gradient";
import { Feather } from "@expo/vector-icons";
import sharlockLogo from "../assets/img/sharlockLogo.png"
import swipeRightImg from "../assets/img/swipeRightAccept.png"
import swipeLeftImg from "../assets/img/swipeLeftDeny.png"
import * as Amplitude from "expo-analytics-amplitude";
const SwiperTest = ({ index, products, onTapCard, onSwipeLeft, onSwipeRight, onSwipeAll, onOpenLink, onRefreshSlider }) => {
const swipeRef = useRef(null);
const windowWidth = Dimensions.get("window").width;
return (
products.length > 0 &&
<Swiper
ref={swipeRef}
containerStyle={{ backgroundColor: "transparent" }
}
cards={products}
stackSize={2}
cardIndex={index}
childrenOnTop={true}
cardVerticalMargin={115}
key={products.length}
animateCardOpacity
verticalSwipe={false}
onTapCard={(index) => { onTapCard(products[index]) }} // Selected item pop modal
onSwipedAll={() => onSwipeAll()} // clear state when all data has been read to get an empty swipe
onSwipedRight={(index) => {
Amplitude.logEventAsync(
"Validée"
).then(() => {
onSwipeRight(products[index])
})
}}
onSwipedLeft={(index) => {
Amplitude.logEventAsync(
"Rejetée"
).then(() => {
onSwipeLeft(products[index])
})
}}
backgroundColor={"#4FD0E9"}
animateOverlayLabelsOpacity //Effect with opacity on label text
inputOverlayLabelsOpacityRangeX={Platform.OS === "ios" ? [-windowWidth / 3, -1, 0, 1, windowWidth / 3] : [-windowWidth/3 , -1, 0, 1, windowWidth/3 ]} // Adjust when the overlay label appears
overlayOpacityHorizontalThreshold={1} // Adjust effect on the overlay
overlayLabels={{
left: {
element: <Image source={swipeLeftImg} style={{ position: "absolute", top: 50, right: 50, width: 100, height: 100 }} />,
},
right: {
element: <Image source={swipeRightImg} style={{ position: "absolute", top: 50, left: 50, width: 100, height: 100 }} />,
},
}}
renderCard={(card, index) =>
<View
key={card.id}
style={styles.offerCard}
>
<ImageBackground
source={{ uri: card.data.picture }}
style={styles.offerBackgroundImg}
>
<LinearGradient
style={styles.offerGradient}
start={{ x: 0, y: 0.5 }}
end={{ x: 0, y: 1 }}
colors={["rgba(0,0,0,0)", "rgba(0,0,0,1)"]}
>
<View
style={{
width: "100%",
position: "absolute",
bottom: 20,
}}
>
<View
style={{
flexDirection: "row",
justifyContent: "space-between",
marginLeft: 15,
marginRight: 15,
}}
>
<View
style={styles.offerPartnerContainer}
>
{card.partner.id === "sharlockTutorial" ?
<Image
source={sharlockLogo}
style={styles.offerLogo}
/>
:
<Image
source={{ uri: card.partner.data.logo }}
style={styles.offerLogo}
/>
}
<Text
style={styles.offerTitle}
>
{card.partner.data.name}
</Text>
</View>
<TouchableOpacity
style={styles.offerLinkBtnContainer}
onPress={() => {
onOpenLink(products[index])
}}
>
<View
style={styles.offerLinkBtn}
>
<Feather
name={"share"}
size={25}
color={"#3300FF"}
/>
</View>
</TouchableOpacity>
</View>
<View
style={styles.offerMargin}
>
<Text
style={styles.offerSubTitle}
>
{card.data.name}
</Text>
<Text
style={styles.offerDescription}
>
{card.data.description.substring(0, 110)}...
</Text>
</View>
</View>
</LinearGradient>
</ImageBackground>
</View>
}
/>
)
}
const styles = StyleSheet.create({
container: {
width: "100%",
height: "100%",
backgroundColor: "#ECECFF",
},
headerTitle: {
fontFamily: "HelveticaNeue",
fontWeight: "700",
fontSize: 22,
},
parentRow: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
},
bubble: {
position: "absolute",
right: 10,
top: -15,
backgroundColor: "#FF3B30",
width: 25,
height: 25,
borderRadius: 15,
alignItems: "center",
justifyContent: "center",
},
bubbleText: {
color: "white",
fontSize: 15,
fontWeight: "700",
fontFamily: "HelveticaNeue",
},
modalActionsBtn: {
width: 60,
height: 60,
backgroundColor: "white",
borderRadius: 30,
alignItems: "center",
justifyContent: "center",
shadowColor: "black",
shadowOpacity: 0.5,
shadowRadius: 5,
shadowOffset: {
width: 0,
height: 5,
},
},
offerCard: {
width: "100%",
height: "100%",
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 1,
},
shadowOpacity: 0.2,
shadowRadius: 1.41,
elevation: 2,
},
offerBackgroundImg: {
flex: 1,
overflow: "hidden",
borderRadius: 20,
},
offerGradient: {
flex: 1,
borderRadius: 20,
},
offerPartnerContainer: {
width: "75%",
flexDirection: "row",
alignItems: "center",
},
offerLogo: {
width: 50,
height: 50,
borderRadius: 10,
},
offerTitle: {
marginLeft: 15,
fontWeight: "700",
fontFamily: "HelveticaNeue",
fontSize: 24,
color: "white",
textTransform: "uppercase",
},
offerLinkBtnContainer: {
zIndex: 99,
width: "25%",
flexDirection: "row",
justifyContent: "flex-end",
},
offerLinkBtn: {
width: 50,
height: 50,
borderRadius: 25,
justifyContent: "center",
alignItems: "center",
alignSelf: "center",
backgroundColor: "white",
},
offerSubTitle: {
fontFamily: "HelveticaNeue",
fontSize: 22,
color: "white",
paddingBottom: 10,
},
offerDescription: {
fontFamily: "HelveticaNeue",
fontSize: 18,
color: "white",
},
offerMargin: {
marginTop: 5,
marginLeft: 15,
marginRight: 15,
}
});
export default SwiperTest
After searching on internet, forums and other similar issues, I wanted to try putting directly without passing the props into the child component. And I realized that the slide worked perfectly on ios/android.
The downside is that I can no longer update my swiper deck by coding like this :
<View style={{
flex: 1,
backgroundColor: "#F5FCFF"
}}>
<Swiper
ref={swipeRef}
containerStyle={{ backgroundColor: "transparent" }
}
cards={offersLikeTinder}
stackSize={2}
cardIndex={index}
childrenOnTop={true}
cardVerticalMargin={115}
key={offersLikeTinder.length}
animateCardOpacity
verticalSwipe={false}
backgroundColor={"#4FD0E9"}
animateOverlayLabelsOpacity //Effect with opacity on label text
inputOverlayLabelsOpacityRangeX={Platform.OS === "ios" ? [-windowWidth / 3, -1, 0, 1, windowWidth / 3] : [-windowWidth / 3, -1, 0, 1, windowWidth / 3]} // Adjust when the overlay label appears
overlayOpacityHorizontalThreshold={1} // Adjust effect on the overlay
overlayLabels={{
left: {
element: <Image source={swipeLeftImg} style={{ position: "absolute", top: 50, right: 50, width: 100, height: 100 }} />,
},
right: {
element: <Image source={swipeRightImg} style={{ position: "absolute", top: 50, left: 50, width: 100, height: 100 }} />,
},
}}
renderCard={(card) => {
return (
<View
key={card.id}
style={styles.offerCard}
>
<ImageBackground
source={{ uri: card.data.picture }}
style={styles.offerBackgroundImg}
>
<LinearGradient
style={styles.offerGradient}
start={{ x: 0, y: 0.5 }}
end={{ x: 0, y: 1 }}
colors={["rgba(0,0,0,0)", "rgba(0,0,0,1)"]}
>
<View
style={{
width: "100%",
position: "absolute",
bottom: 20,
}}
>
<View
style={{
flexDirection: "row",
justifyContent: "space-between",
marginLeft: 15,
marginRight: 15,
}}
>
<View
style={styles.offerPartnerContainer}
>
{card.partner.id === "sharlockTutorial" ?
<Image
source={sharlockLogo}
style={styles.offerLogo}
/>
:
<Image
source={{ uri: card.partner.data.logo }}
style={styles.offerLogo}
/>
}
<Text
style={styles.offerTitle}
>
{card.partner.data.name}
</Text>
</View>
<TouchableOpacity
style={styles.offerLinkBtnContainer}
onPress={() => {
}}
>
<View
style={styles.offerLinkBtn}
>
<Feather
name={"share"}
size={25}
color={"#3300FF"}
/>
</View>
</TouchableOpacity>
</View>
<View
style={styles.offerMargin}
>
<Text
style={styles.offerSubTitle}
>
{card.data.name}
</Text>
<Text
style={styles.offerDescription}
>
{card.data.description.substring(0, 110)}...
</Text>
</View>
</View>
</LinearGradient>
</ImageBackground>
</View>
)
}}
>
</Swiper>
</View>
Here the visual of Deck Swiper when it's import directly without any slide function :
StyleSheet is the same on both tries so if anyone got any idea ;)
Okay it seems that passing props from parent to children fix the problem :
PARENT
<SwiperTest
style={styles.offerCard} //Pass StyleSheet to children
index={index}
products={offersLikeTinder}
onTapCard={tapCard}
onSwipeLeft={swipeLeft}
onSwipeRight={swipeRight}
onSwipeAll={swipeAll}
onOpenLink={openLink}
onRefreshSlider={refreshSlider}
/>
CHILDREN
const SwiperTest = ({ index, products, onTapCard, onSwipeLeft, onSwipeRight, onSwipeAll, onOpenLink, style, onRefreshSlider }) => {
return (
<Swiper
ref={swipeRef}
containerStyle={{ backgroundColor: "transparent" }}
cards={products}
stackSize={2}
cardIndex={index}
childrenOnTop={true}
cardVerticalMargin={115}
key={products.length}
animateCardOpacity
verticalSwipe={false}
onTapCard={(index) => { onTapCard(products[index]) }}
onSwipedAll={() => onSwipeAll()}
onSwipedRight={(index) => { onSwipeRight(products[index]) }}
onSwipedLeft={(index) => {onSwipeLeft(products[index]) }}
backgroundColor={"#4FD0E9"}
animateOverlayLabelsOpacity
inputOverlayLabelsOpacityRangeX={[-windowWidth / 3, -1, 0, 1, windowWidth / 3]}
overlayOpacityHorizontalThreshold={1} // Adjust effect on the overlay
overlayLabels={{
left: {
element: <Image source={swipeLeftImg} style={{ position: "absolute", top: 50, right: 50, width: 100, height: 100 }} />,
},
right: {
element: <Image source={swipeRightImg} style={{ position: "absolute", top: 50, left: 50, width: 100, height: 100 }} />,
},
}}
renderCard={(card, index) =>
<View
key={card.id}
style={style} // <---StyleSheet Props here
>
...