webraptor / react-native-deck-swiper

tinder like react-native deck swiper
ISC License
126 stars 81 forks source link

Vertical scroll #22

Closed rossanodr closed 10 months ago

rossanodr commented 3 years ago

Hi guys, first of all, congrats for this job, its amazing.

I am wondering if its possible to scroll vertically and swipe horizontally. I am asking this because, when the card is too big I cannot see all the content. And I couldn't find any way to solve this :(

thanks!

webraptor commented 3 years ago

Unfortunately the way the swiper is constructed I don't think so. You might achieve this if you disable vertical swipes (verticalSwipe) and release the pan responder when vertical swipe occurs so that it is caught by the inner element.

One of the reasons why we started working on our project with a custom swiper (rather than this package) back 2 years ago was exactly this one.

Another option would be to fiddle with the verticalThreshold, and once a vertical swipe is achieved duplicate the deck, show an identical card (that's not part of the deck) on top, and that would be a scrollable element. But this won't work if users tries to swipe right afterwards.

In order to obtain the desired effect, the core of the swiper should be refactored all together. Not sure if anyone else would be interested. I'll leave this issue open, if the vertical thing is requested enough it might get some attention in the future.

PeterHjHan commented 3 years ago

Tested both on Android and Ios

I also had this same problem, but for me the following solved the issue

  1. set verticalSwipe={false}
  2. On your renderCard Component
import {
  widthPercentageToDP as wp,
  heightPercentageToDP as hp
} from 'react-native-responsive-screen';

<View>
  <ScrollView>
    <TouchableWithoutFeedback>
       <View style={{paddingBottom: hp('15%')}}>
         ...contents
       </View>

    </TouchableWithoutFeedback>
  </ScrollView>

</View>

The paddingBottom is quiet important, as for me, the contents were being cut after a certain amount of scroll, but the padding allowed it the bottom contents to be seen Change the paddingBottom to your desired value to make it seem good on all devices

Aleksandern commented 3 years ago

@PeterHjHan Thanks for your workaround

The paddingBottom is quiet important, as for me, the contents were being cut after a certain amount of scroll, but the padding allowed it the bottom contents to be seen

using height: '100%' in cardStyle prop fixed the cut issue in my case

cardStyle={{
  height: '100%'
}}
TahaAttari commented 3 years ago

In order to obtain the desired effect, the core of the swiper should be refactored all together. Not sure if anyone else would be interested. I'll leave this issue open, if the vertical thing is requested enough it might get some attention in the future.

I don't know if such a drastic change is required, when I put a scrollview in there as one of the cards, I can sometimes get scrolling behaviour if I swipe quickly and vertical swipe is disabled. I think putting in an option for a threshold before the swipe is registered might fix this: i.e. the listener only fires if swipe dx > threshold.

jaroslav009 commented 3 years ago

in node_modules/react-native-deck-swiper/Swiper.js I just add to function pushCardToStack Animated.ScrollView and contentContainerStyle={{paddingBottom: 50}} and it's worked for me. I know its bad but i dont see other way

pushCardToStack = (renderedCards, index, position, key, firstCard) => {

const { cards } = this.props
const stackCardZoomStyle = this.calculateStackCardZoomStyle(position)
const stackCard = this.props.renderCard(cards[index], index)
const swipableCardStyle = this.calculateSwipableCardStyle()
const renderOverlayLabel = this.renderOverlayLabel()
renderedCards.push(
  <Animated.ScrollView
    key={key}
    style={firstCard ? swipableCardStyle : stackCardZoomStyle}
    {...this._panResponder.panHandlers}
    howsVerticalScrollIndicator={false}
    contentContainerStyle={{paddingBottom: 50}}
  >
      {firstCard ? renderOverlayLabel : null}
      {stackCard}
  </Animated.ScrollView>
)

}

TahaAttari commented 3 years ago

IT WORKED

TahaAttari commented 3 years ago

in node_modules/react-native-deck-swiper/Swiper.js I just add to function pushCardToStack Animated.ScrollView and contentContainerStyle={{paddingBottom: 50}} and it's worked for me. I know its bad but i dont see other way pushCardToStack = (renderedCards, index, position, key, firstCard) => { const { cards } = this.props const stackCardZoomStyle = this.calculateStackCardZoomStyle(position) const stackCard = this.props.renderCard(cards[index], index) const swipableCardStyle = this.calculateSwipableCardStyle() const renderOverlayLabel = this.renderOverlayLabel() renderedCards.push( <Animated.ScrollView key={key} style={firstCard ? swipableCardStyle : stackCardZoomStyle} {...this._panResponder.panHandlers} howsVerticalScrollIndicator={false} contentContainerStyle={{paddingBottom: 50}}

{firstCard ? renderOverlayLabel : null} {stackCard} </Animated.ScrollView> ) }

Give this man a medal

also @jaroslav009 you don't need to add paddingBottom:50 if your card has a flex container as the parent element i.e.


< View style={styles.container}> 
//rest of card stuff
 </View>

const styles = StyleSheet.create({
container: {
      flex: 1,
      display: "flex",
      flexDirection: "column",
      justifyContent: "center",
    }
)

It makes it a little bit harder to swipe, so I pulled the horizontalSwipeThreshold all the way down to 30, and it's perfect

jaroslav009 commented 3 years ago

in node_modules/react-native-deck-swiper/Swiper.js I just add to function pushCardToStack Animated.ScrollView and contentContainerStyle={{paddingBottom: 50}} and it's worked for me. I know its bad but i dont see other way pushCardToStack = (renderedCards, index, position, key, firstCard) => { const { cards } = this.props const stackCardZoomStyle = this.calculateStackCardZoomStyle(position) const stackCard = this.props.renderCard(cards[index], index) const swipableCardStyle = this.calculateSwipableCardStyle() const renderOverlayLabel = this.renderOverlayLabel() renderedCards.push( <Animated.ScrollView key={key} style={firstCard ? swipableCardStyle : stackCardZoomStyle} {...this._panResponder.panHandlers} howsVerticalScrollIndicator={false} contentContainerStyle={{paddingBottom: 50}}

{firstCard ? renderOverlayLabel : null} {stackCard} </Animated.ScrollView> ) }

Give this man a medal

also @jaroslav009 you don't need to add paddingBottom:50 if your card has a flex container as the parent element i.e.


< View style={styles.container}> 
//rest of card stuff
 </View>

const styles = StyleSheet.create({
container: {
      flex: 1,
      display: "flex",
      flexDirection: "column",
      justifyContent: "center",
    }
)

It makes it a little bit harder to swipe, so I pulled the horizontalSwipeThreshold all the way down to 30, and it's perfect

thanks)

kieran-osgood commented 3 years ago

Just as a note incase any of you are editing your node_modules directly, use the npm module patch-package - allows you to great git diffs so that if in future you do an npm install the 'patches' will be automatically applied after the installation is complete - avoids you having to manually re-apply and gives you a history of whats been edited :)

Aryk commented 3 years ago

Been working on this for 24 hours with no hope in sight...then I found this.

Thanks so much for putting this solution. 🚀 Seriously...not sure what I would have done without it. Can I buy you a beer? 🍺

One thing to add...for those that want it, you can add bounces={false} makes it a little more responsive on the horizontal swipe after hitting the end with a vertical swipe.

Also...just realized that Im not getting any success with Android. ios works beautifully. Did it work for you on Android with the Animated.ScrollView...it's completely not pressable for me on my Galaxy S8.

in node_modules/react-native-deck-swiper/Swiper.js I just add to function pushCardToStack Animated.ScrollView and contentContainerStyle={{paddingBottom: 50}} and it's worked for me. I know its bad but i dont see other way

pushCardToStack = (renderedCards, index, position, key, firstCard) => {

const { cards } = this.props
const stackCardZoomStyle = this.calculateStackCardZoomStyle(position)
const stackCard = this.props.renderCard(cards[index], index)
const swipableCardStyle = this.calculateSwipableCardStyle()
const renderOverlayLabel = this.renderOverlayLabel()
renderedCards.push(
  <Animated.ScrollView
    key={key}
    style={firstCard ? swipableCardStyle : stackCardZoomStyle}
    {...this._panResponder.panHandlers}
    howsVerticalScrollIndicator={false}
    contentContainerStyle={{paddingBottom: 50}}
  >
      {firstCard ? renderOverlayLabel : null}
      {stackCard}
  </Animated.ScrollView>
)

}

TahaAttari commented 3 years ago

One thing to add...for those that want it, you can add bounces={false} makes it a little more responsive on the horizontal swipe after hitting the end with a vertical swipe.

Also...just realized that Im not getting any success with Android. ios works beautifully. Did it work for you on Android with the Animated.ScrollView...it's completely not pressable for me on my Galaxy S8.

I've not had any issues with this on Android (I test most of my stuff on Android first), it could be a style issue. Flex and layout styles will sometimes behave differently on Android vs iOS.

Aryk commented 3 years ago

Hey @TahaAttari can you paste here your implementation and more specifically the styles you used?

harveyappleton commented 1 year ago

adding <TouchableWithoutFeedback> inside my <ScrollView> on my card render solved it for me without having to patch the package, thanks!!! 🚀

AhmadNaeemK commented 1 year ago

adding <TouchableWithoutFeedback> inside my <ScrollView> on my card render solved it for me without having to patch the package, thanks!!! 🚀

How can I use a flatList with this fix? @harveyappleton

andreweinhorn commented 10 months ago

Just confirming that this is still an issue? I guess I will manually implement a deck-swiper, but would be amazing if someone had come up with a fix for this

webraptor commented 10 months ago

Just confirming that this is still an issue? I guess I will manually implement a deck-swiper, but would be amazing if someone had come up with a fix for this

https://github.com/webraptor/react-native-deck-swiper/issues/22#issuecomment-1416528741