alexbrillant / react-native-deck-swiper Goto Github PK
View Code? Open in Web Editor NEWtinder like react-native deck swiper
License: ISC License
tinder like react-native deck swiper
License: ISC License
Happens with the basic example from README:
Props width
and height
shouldn't be of type string as described here:
https://github.com/alexbrillant/react-native-deck-swiper#overlaylabelwrapperstyle-default-props
Wouldn't it be better to use flexbox and use alignSelf: 'stretch'
?
How can I add a swipe back functionality?
It would be nice if the overlay could be styled as well.
In my case, I would like to apply elevation
and make the colored area span the entire card.
However, that's not possible at the moment. As I've seen it, even things like margin values are hardcoded in the function Swiper.js/calculateOverlayLabelWrapperStyle
.
Maybe a similar approach like the prop cardStyle could be implemented?
Related to issue #33:
Since we can't get buttons on cards to work on some Iphone mobiles (Issue states Iphone 7 and I have same problem with Iphone 6s). I am trying an alternate which is to put buttons outside the swiper.
It works if I follow the below pattern, or the pattern in the usage example. But both patterns render the buttons above the deck.
The difference between the below pattern and the usage pattern is that buttons in the below are not within the swiper component:
return
(
<View style={{ flex: 0}}>
<Swiper
...
</Swiper>
<View style={{ flexDirection: "row", justifyContent: 'space-between' }}>
<Button title="IGNORE" />
<Button title="ACCEPT" />
</View>
</View>
);
If I use the below and click to go to the screen that has the swiper, the transition between screens stops half way:
return
(
<View style={{}}>
<Swiper
...
</Swiper>
<View style={{ flexDirection: "row", justifyContent: 'space-between'}}>
<Button title="LEFT" />
<Button title="RIGHT" />
</View>
</View>
); #
Thanks for the great module. I have been trying to render next card on Right Swipe and previous card on Left Swipe, just like simple swiper. Any idea how can I do that?
If I do this.MySwiperRef.SwipeBottom()
, OnSwipedRight()
gets triggered.
And when I look at the code of Swiper.js
, I see the problem:
swipeLeft = () => {
this.swipeCard(this.props.onSwipedLeft, -this.props.horizontalThreshold);
}
swipeRight = () => {
this.swipeCard(this.props.onSwipedRight, this.props.horizontalThreshold);
}
swipeTop = () => {
this.swipeCard(this.props.onSwipedRight, 0, -this.props.verticalThreshold);
}
swipeBottom = () => {
this.swipeCard(this.props.onSwipedRight, 0, this.props.verticalThreshold);
}
Three over the four above, take this.props.OnSwipedRight
as parameter.
Easy fix and thanks for the good work !
I'm displaying some card with an in it from an external source uri.
After each swipe, the image seems to be reloaded or the source seems to change.
You can see it in action here : link
I'v tried using a caching image plugin but doesn't change anything
I am not able to set cards with this.state method.
When my component did mount it downloads a JSON and i would like to show this JSON in my deck-swiper.
Here are my code and a screenshot:
constructor(props) {
super(props);
this.state = {couponArray: ["hey", "whats", "up"]};
this.state = {loadingViewVisible: false};
}
render(){
return(
<Swiper
cards={this.state.couponArray}
...
cardIndex={0}
backgroundColor={'#000000'}
verticalSwipe={true}
showSecondCard={true}
infinite={true}
cardVerticalMargin={40}
swipeAnimationDuration={200}
secondCardZoom={0.8}
animateCardOpacity={true}>
</Swiper>
);
}
Overtime my component becomes visible it displays following failure:
It would be nice to be able to set the position of Swiper
's children. Something like childrenOnTop
.
I am trying to call Swiper with a list which has only single item but it displays it 2 times. not sure what i am doing wrong or havn't understand it well.
const cards = [ { id: 4, videoFile: '/data/assets/vid.mp4' , name: 'Sovereign Light Cafe'} ]
renderContent(video) {
return (
<View style={{ flex: 1 }} >
<Video source={{ uri: video.videoFile }} />
</View>
);
}
<Swiper
cards={cards}
renderCard={this.renderContent}
onSwipedTop={this.swipedTop}
onSwipedBottom={this.swipedBottom}
infinite
style={{ width, height }}
/>
when i first load it, there are 2 videos playing on the top of each other.
Detects swipe gesture only on the card makes it usable in apps that support swipe to nav to left/right tabs.
Nice work, looks like a great library!
I'd love to see this in action π
When swiping, a nice animation runs after the first card has been swiped away, where the second card increases slightly in scale (by default from 0.97 to 1). When using a separate button press to run the swipe function, this animation doesn't occur.
To reproduce:
<Swiper ref={swiper => { this.swiper = swiper; }} ...
<Button onPress={() => this.swiper.swipeLeft()}>
Observe the missing animation
I hit a really, really strange problem while using this lib with RN 0.44.0 on an android 7.1.2 device.
When I have a stack of 2 or more cards, and I swipe to the last card in the stack, the final card does not appear, and the onSwipedAll event does not fire.
I was able to isolate the problem down to this line in the renderSecondCard
method. When the Swiper is re-rendered after going from a state where renderSecondCard
returns an RN element, to a state where renderSecondCard
returns a null, the first card is not rendered.
I was able to fix the issue by changing the following code:
// This broke
if (notInfinite && lastCardOrSwipedAllCards) {
return null
}
To:
// This worked correctly
if (notInfinite && lastCardOrSwipedAllCards) {
return (
<Animated.View />
)
}
However, it appears that it has to be Animated.View. When I tried substituting a normal View, it broke just like with the null case:
// This also broke
if (notInfinite && lastCardOrSwipedAllCards) {
return (
<View />
)
}
My gut feeling is that this might be an issue with how RN tries to re-use or GCs components, but I'm far too tired to investigate further for now. I would appreciate if you could look into this further, or if you could release a version with the working fix from above. If neither of those are acceptable then I should have some time to look at it in more detail sometime over the weekend.
Hello,
I have cards with buttons on them, however the buttons do not work on iPhone 7 only. Tried several phones. Code:
import React from 'react';
import {Alert, Text, TouchableHighlight, View, StyleSheet} from "react-native";
import Swiper from "react-native-deck-swiper";
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Swiper
ref='swiper'
cards={['asdf','23423']}
renderCard={(question) => {
return (
<TouchableHighlight
onPress={() => Alert.alert('I work')}>
<Text> {question} </Text>
</TouchableHighlight>
)
}}
cardIndex={0}
>
</Swiper>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
Same code without swiper works fine.
import React from 'react';
import {Button, Alert, Text, TouchableHighlight, View, StyleSheet} from "react-native";
import Swiper from "react-native-deck-swiper";
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<TouchableHighlight
onPress={() => Alert.alert('asdf')}>
<Text> I like pants </Text>
</TouchableHighlight>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
I highly appreciate any help. Thanks!
i tried to use code from App.js file from examples demo folder and swipeBack function doesn't work like i was expected to swipe one item back. Instead It swipes on first item of the cards array and when you try to swipe cards after that at the third card it does the same thing without clicking on a swipe back button
onSwipedAllCards = () => {
this.setState({
swipedAllCards: true
})
};
swipeBack = () => {
if (!this.state.isSwipingBack) {
this.setIsSwipingBack(true, () => {
this.swiper.swipeBack(() => {
this.setIsSwipingBack(false)
})
})
}
};
And i saw that there is goBackToPreviousCardOnSwipeLeft/Right/Top/Bottom props
but can we used that on a button click instead of swipe ?
You kind of have this mentioned in your README, but I figure it's worth tracking development.
It would be nice to have the next card peeking out from the bottom of the current card, as a hint for users to visually know that they can swipe.
What needs to be done to make this a reality:
I am using some images in deck swiper. So on clicking in any of the images, I have to pass the current image to next page. So can you tell me how to know the current image?
I'm setting my cardIndex to 5 but it's also starting with the first card?
When you want to create a UI like Tinder where there are buttons to trigger actions as alternative to swiping.
can I show or swipe any card forcefully from any external functional like below code
<ListView ref={(comp) => { this._refPreviewListView = comp; return; }} /> this._refPreviewListView.scrollTo({ x: 100 });
I want to add all cards at bottom with thumbnail size with change of card bottom cards should move and vice versa and want to apply pagination to it
?????
thanks!
The interpolate opacity method doesn't work properly. Tested it thoroughly on an iPhone 6 with a card in portrait mode and only Oy axis gets animated.
IE: swiping card to top and bottom applies opacity interpolation, swiping it left and right doesn't apply any interpolation and the card remains at opacity 1 throughout the swipe movement.
`
interpolateOpacity = () => {
const animatedValueX = Math.abs(this._animatedValueX);
const animatedValueY = Math.abs(this._animatedValueY);
let opacity;
if (animatedValueX > animatedValueY) {
opacity = this.state.pan.x.interpolate({
inputRange: this.props.inputOpacityRangeX,
outputRange: this.props.outputOpacityRangeX
});
} else {
opacity = this.state.pan.y.interpolate({
inputRange: this.props.inputOpacityRangeY,
outputRange: this.props.outputOpacityRangeY
});
}
return opacity;
};
`
Card height/width are currently calculated from window dimensions.
[...]This works well for a full screen deck swiper. However, it's not correct if the deck swiper is used inside a container with other dimensions. Cards currently will overflow and most likely render partially outside of the screen. My specific use case is having a header and a deck container that grows to fill remaining screen size.
I suggest updating implementation so that card dimensions are calculated from the Swiper component dimensions, instead of the window.
Thoughts?
I load 15 items from the server and add them to the Swiper, when I viewed 11 items, I load 15 new items, throw out the 11 already viewed and add the new ones behind the remaining 4.
Problem is now, that the swiper freezes when I do this. Sometimes it completes the current swipe after the update, sometimes it simply keeps stuck till I swipe again.
if (itemsLeft < 5) {
const nextPage = page + 1;
const nextItems = await this.loadPage(nextPage);
items.splice(0, items.length - itemsLeft);
this.setState({
items: [...items, ...nextItems],
page: nextPage
});
}
Right now we need to swipe to "ignore" current card and view next card.
I was wondering if we can implement a GoToNextCard()
?
Usage would be similar to swipeBack()
and jumpToCardIndex()
but it does not require any parameters. Then it jumps to the next card:
<Swiper ref={ (swiper) => { this._swiper = swiper }}
<Button onPress={() => {this._swiper.GoToNextCard()}} title="Ignore current card"/>
</Swiper>
Right now I am trying this ugly approach where if jumpToCardIndex() takes no parameters I want to go to next card. But it is not working:
jumpToCardIndex = newCardIndex => {
if(newCardIndex === undefined) // if I did not pass parameters
{
this.setState(
{
firstCardIndex: this.state.firstCardIndex + 1, // increment
secondCardIndex: this.calculateSecondCardIndex(this.state.firstCardIndex + 1),
previousCardIndex: this.calculatePreviousCardIndex(this.state.firstCardIndex + 1),
swipedAllCards: swipedAllCards,
panResponderLocked: false
},
this.resetPanAndScale
);
}
else
{
if (this.props.cards[newCardIndex])
{
this.setCardIndex(newCardIndex, false);
}
}
};
And it would be perfect if it gets "ignored" on a button click with exact animation when swiping it! (Not just flickers, it actually moves to a direction and then disappears)
Beautiful work guys and thanks!
Swiping on empty deck triggers onSwipeX callbacks when it shouldn't .
I have a modal that presents whenever the user swipes Right. The view is presented by setting a isModalVisible state variable. However, when I dismiss the modal view, the card stack resets to the first card. Why does this occur and how do I fix this?
Here is my code:
<Swiper
ref={swiper => {
this.swiper = swiper;
}}
infinite={true}
cards={this.state.cards}
cardIndex={this.state.cardIndex}
cardVerticalMargin={(Platform.OS === 'ios') ? 15: 160}
marginTop={(Platform.OS === 'ios') ? 0: -150}
marginBottom={(Platform.OS === 'ios') ? 115 : 0}
backgroundColor={'#ffffff'}
renderCard={this.renderCard}
onSwipedAll={this.onSwipedAllCards}
onSwiped={this.onSwiped}
onSwipedRight={this.handleYup}
onSwipedLeft={this.handleNope}
showSecondCard={true}
overlayLabels={{
bottom: {
title: 'BLEAH',
swipeColor: '#9262C2',
backgroundOpacity: '0.75',
fontColor: '#FFF'
},
left: {
title: 'NOPE',
swipeColor: '#FF6C6C',
backgroundOpacity: '0.75',
fontColor: '#FFF'
},
right: {
title: 'LIKE',
swipeColor: '#4CCC93',
backgroundOpacity: '0.75',
fontColor: '#FFF'
},
top: {
title: 'SUPER LIKE',
swipeColor: '#4EB8B7',
backgroundOpacity: '0.75',
fontColor: '#FFF'
}
}}
animateOverlayLabelsOpacity
animateCardOpacity
>
</Swiper>
I want to know direction of swiper to do some thing. Ex: Vote up if direction is the right side, and otherwise. :D
i am trying to implement vertical card swiper with infinity loading.
It would be useful to allow for disableBottomSwipe and the other similar props to be booleans or functions that return a boolean, to allow clients to enable or disable swipe directions per-card.
It might look something like:
<Swiper
cards={ [ /* ... */ ] }
disableTopSwipe={
card => card.canSwipeUp
} />
Adding swipe labels broke swipe back feature
Hi,
I would like to add an event on double click in card, how can I easily do?
Thanks
it sits here and does not install βΈ¨ ββββββββββββΈ© β ¦ extract:react-native-deck-swiper: verb lock using /Users
First of all, thank you for the awesome library.
I have the following issue: while swiping cards, when I have few cards left, I make a request to server to add additional data. I use redux, catch new props and make setState(). Therefore, I add new cards to my Swiper.
Let's say I have 9 cards and load additional data when 3 cards are left. Till the 9'th card everything works fine. When I try to swipe the 9'th card, no new cards are rendered behind it - I see a blank view (though I know that new cards are already in the state). Immediately after the swipe of the that card (when swipe event is triggered), it makes new cards visible with no additional actions from me. And everything works fine again.
Thank you for your help.
I have a constructor that creates a cardIndex state of 0 by default.
constructor(props) {
super(props);
this.state = {
confirm: false,
cardIndex: 0
}
}
I have another function that changes the state.
changeView = () => {
this.setState({
confirm: true
cardIndex: 1
})
this.swiper.jumpToCardIndex(this.state.cardIndex)
}
Terms.setStateCallBack(this.changeView);
This function is called from another component using a callback.
let callbackSetState;
Terms.setStateCallBack = (callback) => {
callbackSetState = callback;
}
Terms.actions = <View style={styles.container}>
<Button style={styles.text} containerStyle={styles.redeemButton} onPress = {() => callbackSetState()} >
Redeem now
</Button>
</View>
And in my swiper component I set the cardIndex to this.state.cardIndex
<Swiper style={styles.swiper}
cards={[About, Terms]}
cardIndex = {this.state.cardIndex}
However even when the state is updated when I click on the redeem button, the swiper cardIndex always render 0 first. In other words, I will have to swipe right again to be able to click on the confirm/cancel button. The expected behaviour should be that after the redeem button is pressed, the swiper should automatically render with cardIndex 1 and the confirm/cancel button.
Using console.log(this.state.cardIndex), I know that the state is changing correctly. But cardIndex on swiper isn't rendering the correct card.
Can someone help me?
These are my cards so it's easier for you to visualise.
Is there a way to apply justifyContent: 'center' to the card?
I can't center it vertically.
I want the swiper to render previous card on rightSwipe. I have a method(renderPreviousCard) that is called when 'onSwipedRight' event is fired. In renderPreviousCard function 'jumpToCardIndex' is used with swiper's reference. 'jumpToCardIndex' is not working.
<Swiper
infinite={true}
cardIndex={0}
showSecondCard={false}
cardVerticalMargin={0}
cardHorizontalMargin={0}
verticalSwipe={false}
cards={this.state.demoArray}
renderCard={(card) => this.renderCardMethod(card)}
onSwiped={(cardIndex) => {console.log(cardIndex)}}
onSwipedAll={() => {console.log('onSwipedAll')}}
backgroundColor={'white'}
onSwipedRight={(cardIndex) => this.renderPreviousCard(cardIndex)}
ref={(ref) => {this.swiperReference = ref}}>
</Swiper>
renderPreviousCard = (cardIndex) =>{
this.swiperReference.jumpToCardIndex(cardIndex-1);
}
NOTE: The 'jumpToCardIndex' is working in other scenarios. Whenever the 'jumpToCardIndex' method is within the scope of functions called from the swiper props/events.
How to change the background color of main container to white. I am not able to change that blue kind of color to white.. please tell me
It is useful to be able to set a fixed width/height to the Swiper container, but the current API doesn't allow it.
I needed to have two swipers on the same screen, and couldn't get this, so I had to modify the package.
This can be simply achieved by changing the following on the Swiper render method:
<View
style={[
styles.container,
{
+ height: this.props.height,
+ width: this.props.width,
backgroundColor: this.props.backgroundColor,
marginTop: this.props.marginTop,
marginBottom: this.props.marginBottom
}
]}
>
I would prefer to just allow users to throw in a style
prop into the Swiper component, perhaps discarding those styles you wouldn't like to accept.
I can throw a PR in if you like.
PS: Awesome package, Alex!
Thanks for the great work! Just wondering if it's possible to use flex layout on the Swiper
instead of absolute so it's easier to config it's layout?
I have't dive deep into the src code to learn if position: absolute
is critical. If it's not I'm willing to help :)
There's a similar request out there for double-tap, but let's separate them out; this one should be easier.
We want a function that's called when a user taps on the card. While this could be implemented at the card level relatively easily, the abstraction level is convenient.
Updating Swiper cards sent as argument doesn't trigger cardIndex reset and neither does it trigger rendering of Swiper component.
Steps to reproduce:
Possible fixes
I have children components that are on the last screen (once all the cards are gone), but I can't position them correctly, because you are missing the top,left,right, bottom on the childrenViewStyle style.
Please update with:
childrenViewStyle: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0
},
Hello,
First, thank you for your great work @alexbrillant !
I have a problem with the swiper on android only.
When I swipe I have the red screen with: "The specified child already has a parent. You must call removeView() on the child's parents first".
I have no idea why it's working on ios and not android.
Here a part of my code:
<Swiper
ref={(swiper) => { this._swiper = swiper; }}
cards={adsCards}
renderCard={this._renderCard}
infinite={true}
verticalSwipe={false}
onSwiped={(index) => { this._handleSwipeCard(index + 1); }}
cardIndex={0}
cardHorizontalMargin={0}
cardVerticalMargin={0}
cardStyle={this.state.size}
backgroundColor="transparent"
goBackToPreviousCardOnSwipeRight={true}
/>
Did I miss something ?
Thank you !
"react-native": "0.44.2"
"react-native-deck-swiper": "^1.3.7"
Marina
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.