How do I make a secondary enter a main view with the PanResponder?









up vote
1
down vote

favorite












When the View mounts, I would like the secondary view to be off the screen to the right of the main view.



When the user pan swipes left, the secondary view should follow the pan and eventually cover the main view. (like Instagram camera)



I have a basic structure set up, but I'm not sure how to finalize the <Animated.View> part. For example, do I put the pan handler on the main view or on the secondary view? I don't want the secondary view to cover any interactions on the main view.



import React from 'react';
import PanResponder, Animated, Dimensions, StyleSheet, Text, View from 'react-native';
const winWidth = Dimensions.get('window').width
const winHeight = Dimensions.get('window').height

class Main extends React.Component
constructor(props)
super(props);

translateX = new Animated.Value(0);
panResponder = PanResponder.create(
onMoveShouldSetPanResponderCapture: (e, gs) =>
return gs.dx < 0 //allow left only
,
onPanResponderMove: (e, gs) =>
if(gs.dx < 0)
Animated.event([null, dx: this.translateX])(e, gs)

,
onPanResponderRelease: (e, vx, dx) =>
//Secondary View should now cover the main View
,
onPanResponderTerminationRequest: (e, gs) =>
return false
,
onPanResponderTerminate: (e, vx, dx ) =>
,
)
render()
return(
<View style=styles.main>
<View style=styles.secondary></View>
<View><Text>Other components will be displayed</Text></View>
</View>
)



const styles = StyleSheet.create(
main:
flex:1,
flexDirection:'column',
backgroundColor: '#ffffff'
,
secondary:
width: winWidth,
height: winHeight,
backgroundColor: 'red',
position: 'absolute',
top:0,
left:winWidth, //start off screen
,
)









share|improve this question





















  • Never had to deal with panhandler myself, I use this awesome library kmagiera.github.io/react-native-gesture-handler/docs/…
    – Ziyo
    Nov 12 at 0:52














up vote
1
down vote

favorite












When the View mounts, I would like the secondary view to be off the screen to the right of the main view.



When the user pan swipes left, the secondary view should follow the pan and eventually cover the main view. (like Instagram camera)



I have a basic structure set up, but I'm not sure how to finalize the <Animated.View> part. For example, do I put the pan handler on the main view or on the secondary view? I don't want the secondary view to cover any interactions on the main view.



import React from 'react';
import PanResponder, Animated, Dimensions, StyleSheet, Text, View from 'react-native';
const winWidth = Dimensions.get('window').width
const winHeight = Dimensions.get('window').height

class Main extends React.Component
constructor(props)
super(props);

translateX = new Animated.Value(0);
panResponder = PanResponder.create(
onMoveShouldSetPanResponderCapture: (e, gs) =>
return gs.dx < 0 //allow left only
,
onPanResponderMove: (e, gs) =>
if(gs.dx < 0)
Animated.event([null, dx: this.translateX])(e, gs)

,
onPanResponderRelease: (e, vx, dx) =>
//Secondary View should now cover the main View
,
onPanResponderTerminationRequest: (e, gs) =>
return false
,
onPanResponderTerminate: (e, vx, dx ) =>
,
)
render()
return(
<View style=styles.main>
<View style=styles.secondary></View>
<View><Text>Other components will be displayed</Text></View>
</View>
)



const styles = StyleSheet.create(
main:
flex:1,
flexDirection:'column',
backgroundColor: '#ffffff'
,
secondary:
width: winWidth,
height: winHeight,
backgroundColor: 'red',
position: 'absolute',
top:0,
left:winWidth, //start off screen
,
)









share|improve this question





















  • Never had to deal with panhandler myself, I use this awesome library kmagiera.github.io/react-native-gesture-handler/docs/…
    – Ziyo
    Nov 12 at 0:52












up vote
1
down vote

favorite









up vote
1
down vote

favorite











When the View mounts, I would like the secondary view to be off the screen to the right of the main view.



When the user pan swipes left, the secondary view should follow the pan and eventually cover the main view. (like Instagram camera)



I have a basic structure set up, but I'm not sure how to finalize the <Animated.View> part. For example, do I put the pan handler on the main view or on the secondary view? I don't want the secondary view to cover any interactions on the main view.



import React from 'react';
import PanResponder, Animated, Dimensions, StyleSheet, Text, View from 'react-native';
const winWidth = Dimensions.get('window').width
const winHeight = Dimensions.get('window').height

class Main extends React.Component
constructor(props)
super(props);

translateX = new Animated.Value(0);
panResponder = PanResponder.create(
onMoveShouldSetPanResponderCapture: (e, gs) =>
return gs.dx < 0 //allow left only
,
onPanResponderMove: (e, gs) =>
if(gs.dx < 0)
Animated.event([null, dx: this.translateX])(e, gs)

,
onPanResponderRelease: (e, vx, dx) =>
//Secondary View should now cover the main View
,
onPanResponderTerminationRequest: (e, gs) =>
return false
,
onPanResponderTerminate: (e, vx, dx ) =>
,
)
render()
return(
<View style=styles.main>
<View style=styles.secondary></View>
<View><Text>Other components will be displayed</Text></View>
</View>
)



const styles = StyleSheet.create(
main:
flex:1,
flexDirection:'column',
backgroundColor: '#ffffff'
,
secondary:
width: winWidth,
height: winHeight,
backgroundColor: 'red',
position: 'absolute',
top:0,
left:winWidth, //start off screen
,
)









share|improve this question













When the View mounts, I would like the secondary view to be off the screen to the right of the main view.



When the user pan swipes left, the secondary view should follow the pan and eventually cover the main view. (like Instagram camera)



I have a basic structure set up, but I'm not sure how to finalize the <Animated.View> part. For example, do I put the pan handler on the main view or on the secondary view? I don't want the secondary view to cover any interactions on the main view.



import React from 'react';
import PanResponder, Animated, Dimensions, StyleSheet, Text, View from 'react-native';
const winWidth = Dimensions.get('window').width
const winHeight = Dimensions.get('window').height

class Main extends React.Component
constructor(props)
super(props);

translateX = new Animated.Value(0);
panResponder = PanResponder.create(
onMoveShouldSetPanResponderCapture: (e, gs) =>
return gs.dx < 0 //allow left only
,
onPanResponderMove: (e, gs) =>
if(gs.dx < 0)
Animated.event([null, dx: this.translateX])(e, gs)

,
onPanResponderRelease: (e, vx, dx) =>
//Secondary View should now cover the main View
,
onPanResponderTerminationRequest: (e, gs) =>
return false
,
onPanResponderTerminate: (e, vx, dx ) =>
,
)
render()
return(
<View style=styles.main>
<View style=styles.secondary></View>
<View><Text>Other components will be displayed</Text></View>
</View>
)



const styles = StyleSheet.create(
main:
flex:1,
flexDirection:'column',
backgroundColor: '#ffffff'
,
secondary:
width: winWidth,
height: winHeight,
backgroundColor: 'red',
position: 'absolute',
top:0,
left:winWidth, //start off screen
,
)






ios react-native view






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 11 at 22:03









TIMEX

67.3k268645947




67.3k268645947











  • Never had to deal with panhandler myself, I use this awesome library kmagiera.github.io/react-native-gesture-handler/docs/…
    – Ziyo
    Nov 12 at 0:52
















  • Never had to deal with panhandler myself, I use this awesome library kmagiera.github.io/react-native-gesture-handler/docs/…
    – Ziyo
    Nov 12 at 0:52















Never had to deal with panhandler myself, I use this awesome library kmagiera.github.io/react-native-gesture-handler/docs/…
– Ziyo
Nov 12 at 0:52




Never had to deal with panhandler myself, I use this awesome library kmagiera.github.io/react-native-gesture-handler/docs/…
– Ziyo
Nov 12 at 0:52












1 Answer
1






active

oldest

votes

















up vote
1
down vote



accepted










I am not sure if this is what you are after but the way I did it was nesting two View inside the Animated.View Component which cover the full screen.



<Animated.View style=[this.position.getLayout(), display: 'flex', flex: 1, flexDirection: 'row'] ...this.panResponder.panHandlers>
<View style=width: '100%', height: '100%', backgroundColor: 'yellow'>
<Text>
This is the Main view
</Text>
</View>

<View style= height: '100%', width: '100%', backgroundColor: 'red'>
<Text>
This is the invisible View
</Text>
</View>
</Animated.View>


  • The styling in the Views is to make each cover the full width


  • inside the Animated.View I used the array notation to apply two styles


  • this.position.getLayout() is the one that gives the coordinates/position of where the Animated.View component should be


  • The other styling object is so we can render the child views next to each other using flexbox particularly setting



  • Also attach the panHandlers to the Animated.View



    constructor(props)
    super(props)
    position = new Animated.ValueXY()

    const panResponder = PanResponder.create(
    onStartShouldSetPanResponder: ()=> true,
    onPanResponderMove: (evt, gesture)=>
    //Need to set theshhold and state.isOpen to determine direction here
    position.setValue(x: gesture.dx, y: 0)
    ,
    onPanResponderGrant: ()=>
    this.position.setOffset(x: this.position.x._value, y: 0)
    this.position.setValue(x: 0, y: 0)
    ,
    onPanResponderRelease: ()=>
    this.openOrClose()

    )

    this.state = isOpen: false
    this.panResponder = panResponder
    this.position = position



  • I used state to monitor where the View Should move to this.state = isOpen: false depending on which view was visible.


  • The functions to move are mainly position.setValue(x: gesture.dx, y: 0) which tracks the movement while the touch/pan is still active and this.openOrClose() which is called when the touch/pan is released.


  • The openOrClose function determines how to handle the movement and the main logic should be here. I just did a simple case and did not include any threshHold in this example.


  • To understand panHandlers I suggest you read this article as it explains the reasons for onPanResponderGrant best.


Below is the code for the working Component






import React, Component from 'react'
import View, Text, Animated, PanResponder, Dimensions from 'react-native'

const ScreenWidth = Dimensions.get('window').width

//Logic to flattenOffset required
export class Swipable extends Component
constructor(props)
super(props)
position = new Animated.ValueXY()

const panResponder = PanResponder.create(
onStartShouldSetPanResponder: ()=> true,
onPanResponderMove: (evt, gesture)=>
//Need to set theshhold and state.isOpen to determine direction here
position.setValue(x: gesture.dx, y: 0)
,
onPanResponderGrant: ()=>
this.position.setOffset(x: this.position.x._value, y: 0)
this.position.setValue(x: 0, y: 0)
,
onPanResponderRelease: ()=>
this.openOrClose()

)

this.state = isOpen: false
this.panResponder = panResponder
this.position = position


openOrClose = ()=>
this.position.flattenOffset()
//determine where to move depending onState
direction = this.state.isOpen ? 0 : -ScreenWidth

Animated.spring(this.position,
toValue: x: direction, y: 0
).start(()=>
//Callback when animation is complete to show if open or closed
this.setState((prevState)=>
return isOpen: !prevState.isOpen
)
)


render()
return(
<Animated.View style=[this.position.getLayout(), display: 'flex', flex: 1, flexDirection: 'row'] ...this.panResponder.panHandlers>
<View style=width: '100%', height: '100%', backgroundColor: 'yellow'>
<Text>
This is the Main view
</Text>
</View>

<View style= height: '100%', width: '100%', backgroundColor: 'red'>
<Text>
This is the invisible View
</Text>
</View>
</Animated.View>
)






I ran the above code on an Android emulator, I am sure it will work on ios. If there is anything I need to clarify or improve please do tell me






share|improve this answer






















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53253709%2fhow-do-i-make-a-secondary-view-enter-a-main-view-with-the-panresponder%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    1
    down vote



    accepted










    I am not sure if this is what you are after but the way I did it was nesting two View inside the Animated.View Component which cover the full screen.



    <Animated.View style=[this.position.getLayout(), display: 'flex', flex: 1, flexDirection: 'row'] ...this.panResponder.panHandlers>
    <View style=width: '100%', height: '100%', backgroundColor: 'yellow'>
    <Text>
    This is the Main view
    </Text>
    </View>

    <View style= height: '100%', width: '100%', backgroundColor: 'red'>
    <Text>
    This is the invisible View
    </Text>
    </View>
    </Animated.View>


    • The styling in the Views is to make each cover the full width


    • inside the Animated.View I used the array notation to apply two styles


    • this.position.getLayout() is the one that gives the coordinates/position of where the Animated.View component should be


    • The other styling object is so we can render the child views next to each other using flexbox particularly setting



    • Also attach the panHandlers to the Animated.View



      constructor(props)
      super(props)
      position = new Animated.ValueXY()

      const panResponder = PanResponder.create(
      onStartShouldSetPanResponder: ()=> true,
      onPanResponderMove: (evt, gesture)=>
      //Need to set theshhold and state.isOpen to determine direction here
      position.setValue(x: gesture.dx, y: 0)
      ,
      onPanResponderGrant: ()=>
      this.position.setOffset(x: this.position.x._value, y: 0)
      this.position.setValue(x: 0, y: 0)
      ,
      onPanResponderRelease: ()=>
      this.openOrClose()

      )

      this.state = isOpen: false
      this.panResponder = panResponder
      this.position = position



    • I used state to monitor where the View Should move to this.state = isOpen: false depending on which view was visible.


    • The functions to move are mainly position.setValue(x: gesture.dx, y: 0) which tracks the movement while the touch/pan is still active and this.openOrClose() which is called when the touch/pan is released.


    • The openOrClose function determines how to handle the movement and the main logic should be here. I just did a simple case and did not include any threshHold in this example.


    • To understand panHandlers I suggest you read this article as it explains the reasons for onPanResponderGrant best.


    Below is the code for the working Component






    import React, Component from 'react'
    import View, Text, Animated, PanResponder, Dimensions from 'react-native'

    const ScreenWidth = Dimensions.get('window').width

    //Logic to flattenOffset required
    export class Swipable extends Component
    constructor(props)
    super(props)
    position = new Animated.ValueXY()

    const panResponder = PanResponder.create(
    onStartShouldSetPanResponder: ()=> true,
    onPanResponderMove: (evt, gesture)=>
    //Need to set theshhold and state.isOpen to determine direction here
    position.setValue(x: gesture.dx, y: 0)
    ,
    onPanResponderGrant: ()=>
    this.position.setOffset(x: this.position.x._value, y: 0)
    this.position.setValue(x: 0, y: 0)
    ,
    onPanResponderRelease: ()=>
    this.openOrClose()

    )

    this.state = isOpen: false
    this.panResponder = panResponder
    this.position = position


    openOrClose = ()=>
    this.position.flattenOffset()
    //determine where to move depending onState
    direction = this.state.isOpen ? 0 : -ScreenWidth

    Animated.spring(this.position,
    toValue: x: direction, y: 0
    ).start(()=>
    //Callback when animation is complete to show if open or closed
    this.setState((prevState)=>
    return isOpen: !prevState.isOpen
    )
    )


    render()
    return(
    <Animated.View style=[this.position.getLayout(), display: 'flex', flex: 1, flexDirection: 'row'] ...this.panResponder.panHandlers>
    <View style=width: '100%', height: '100%', backgroundColor: 'yellow'>
    <Text>
    This is the Main view
    </Text>
    </View>

    <View style= height: '100%', width: '100%', backgroundColor: 'red'>
    <Text>
    This is the invisible View
    </Text>
    </View>
    </Animated.View>
    )






    I ran the above code on an Android emulator, I am sure it will work on ios. If there is anything I need to clarify or improve please do tell me






    share|improve this answer


























      up vote
      1
      down vote



      accepted










      I am not sure if this is what you are after but the way I did it was nesting two View inside the Animated.View Component which cover the full screen.



      <Animated.View style=[this.position.getLayout(), display: 'flex', flex: 1, flexDirection: 'row'] ...this.panResponder.panHandlers>
      <View style=width: '100%', height: '100%', backgroundColor: 'yellow'>
      <Text>
      This is the Main view
      </Text>
      </View>

      <View style= height: '100%', width: '100%', backgroundColor: 'red'>
      <Text>
      This is the invisible View
      </Text>
      </View>
      </Animated.View>


      • The styling in the Views is to make each cover the full width


      • inside the Animated.View I used the array notation to apply two styles


      • this.position.getLayout() is the one that gives the coordinates/position of where the Animated.View component should be


      • The other styling object is so we can render the child views next to each other using flexbox particularly setting



      • Also attach the panHandlers to the Animated.View



        constructor(props)
        super(props)
        position = new Animated.ValueXY()

        const panResponder = PanResponder.create(
        onStartShouldSetPanResponder: ()=> true,
        onPanResponderMove: (evt, gesture)=>
        //Need to set theshhold and state.isOpen to determine direction here
        position.setValue(x: gesture.dx, y: 0)
        ,
        onPanResponderGrant: ()=>
        this.position.setOffset(x: this.position.x._value, y: 0)
        this.position.setValue(x: 0, y: 0)
        ,
        onPanResponderRelease: ()=>
        this.openOrClose()

        )

        this.state = isOpen: false
        this.panResponder = panResponder
        this.position = position



      • I used state to monitor where the View Should move to this.state = isOpen: false depending on which view was visible.


      • The functions to move are mainly position.setValue(x: gesture.dx, y: 0) which tracks the movement while the touch/pan is still active and this.openOrClose() which is called when the touch/pan is released.


      • The openOrClose function determines how to handle the movement and the main logic should be here. I just did a simple case and did not include any threshHold in this example.


      • To understand panHandlers I suggest you read this article as it explains the reasons for onPanResponderGrant best.


      Below is the code for the working Component






      import React, Component from 'react'
      import View, Text, Animated, PanResponder, Dimensions from 'react-native'

      const ScreenWidth = Dimensions.get('window').width

      //Logic to flattenOffset required
      export class Swipable extends Component
      constructor(props)
      super(props)
      position = new Animated.ValueXY()

      const panResponder = PanResponder.create(
      onStartShouldSetPanResponder: ()=> true,
      onPanResponderMove: (evt, gesture)=>
      //Need to set theshhold and state.isOpen to determine direction here
      position.setValue(x: gesture.dx, y: 0)
      ,
      onPanResponderGrant: ()=>
      this.position.setOffset(x: this.position.x._value, y: 0)
      this.position.setValue(x: 0, y: 0)
      ,
      onPanResponderRelease: ()=>
      this.openOrClose()

      )

      this.state = isOpen: false
      this.panResponder = panResponder
      this.position = position


      openOrClose = ()=>
      this.position.flattenOffset()
      //determine where to move depending onState
      direction = this.state.isOpen ? 0 : -ScreenWidth

      Animated.spring(this.position,
      toValue: x: direction, y: 0
      ).start(()=>
      //Callback when animation is complete to show if open or closed
      this.setState((prevState)=>
      return isOpen: !prevState.isOpen
      )
      )


      render()
      return(
      <Animated.View style=[this.position.getLayout(), display: 'flex', flex: 1, flexDirection: 'row'] ...this.panResponder.panHandlers>
      <View style=width: '100%', height: '100%', backgroundColor: 'yellow'>
      <Text>
      This is the Main view
      </Text>
      </View>

      <View style= height: '100%', width: '100%', backgroundColor: 'red'>
      <Text>
      This is the invisible View
      </Text>
      </View>
      </Animated.View>
      )






      I ran the above code on an Android emulator, I am sure it will work on ios. If there is anything I need to clarify or improve please do tell me






      share|improve this answer
























        up vote
        1
        down vote



        accepted







        up vote
        1
        down vote



        accepted






        I am not sure if this is what you are after but the way I did it was nesting two View inside the Animated.View Component which cover the full screen.



        <Animated.View style=[this.position.getLayout(), display: 'flex', flex: 1, flexDirection: 'row'] ...this.panResponder.panHandlers>
        <View style=width: '100%', height: '100%', backgroundColor: 'yellow'>
        <Text>
        This is the Main view
        </Text>
        </View>

        <View style= height: '100%', width: '100%', backgroundColor: 'red'>
        <Text>
        This is the invisible View
        </Text>
        </View>
        </Animated.View>


        • The styling in the Views is to make each cover the full width


        • inside the Animated.View I used the array notation to apply two styles


        • this.position.getLayout() is the one that gives the coordinates/position of where the Animated.View component should be


        • The other styling object is so we can render the child views next to each other using flexbox particularly setting



        • Also attach the panHandlers to the Animated.View



          constructor(props)
          super(props)
          position = new Animated.ValueXY()

          const panResponder = PanResponder.create(
          onStartShouldSetPanResponder: ()=> true,
          onPanResponderMove: (evt, gesture)=>
          //Need to set theshhold and state.isOpen to determine direction here
          position.setValue(x: gesture.dx, y: 0)
          ,
          onPanResponderGrant: ()=>
          this.position.setOffset(x: this.position.x._value, y: 0)
          this.position.setValue(x: 0, y: 0)
          ,
          onPanResponderRelease: ()=>
          this.openOrClose()

          )

          this.state = isOpen: false
          this.panResponder = panResponder
          this.position = position



        • I used state to monitor where the View Should move to this.state = isOpen: false depending on which view was visible.


        • The functions to move are mainly position.setValue(x: gesture.dx, y: 0) which tracks the movement while the touch/pan is still active and this.openOrClose() which is called when the touch/pan is released.


        • The openOrClose function determines how to handle the movement and the main logic should be here. I just did a simple case and did not include any threshHold in this example.


        • To understand panHandlers I suggest you read this article as it explains the reasons for onPanResponderGrant best.


        Below is the code for the working Component






        import React, Component from 'react'
        import View, Text, Animated, PanResponder, Dimensions from 'react-native'

        const ScreenWidth = Dimensions.get('window').width

        //Logic to flattenOffset required
        export class Swipable extends Component
        constructor(props)
        super(props)
        position = new Animated.ValueXY()

        const panResponder = PanResponder.create(
        onStartShouldSetPanResponder: ()=> true,
        onPanResponderMove: (evt, gesture)=>
        //Need to set theshhold and state.isOpen to determine direction here
        position.setValue(x: gesture.dx, y: 0)
        ,
        onPanResponderGrant: ()=>
        this.position.setOffset(x: this.position.x._value, y: 0)
        this.position.setValue(x: 0, y: 0)
        ,
        onPanResponderRelease: ()=>
        this.openOrClose()

        )

        this.state = isOpen: false
        this.panResponder = panResponder
        this.position = position


        openOrClose = ()=>
        this.position.flattenOffset()
        //determine where to move depending onState
        direction = this.state.isOpen ? 0 : -ScreenWidth

        Animated.spring(this.position,
        toValue: x: direction, y: 0
        ).start(()=>
        //Callback when animation is complete to show if open or closed
        this.setState((prevState)=>
        return isOpen: !prevState.isOpen
        )
        )


        render()
        return(
        <Animated.View style=[this.position.getLayout(), display: 'flex', flex: 1, flexDirection: 'row'] ...this.panResponder.panHandlers>
        <View style=width: '100%', height: '100%', backgroundColor: 'yellow'>
        <Text>
        This is the Main view
        </Text>
        </View>

        <View style= height: '100%', width: '100%', backgroundColor: 'red'>
        <Text>
        This is the invisible View
        </Text>
        </View>
        </Animated.View>
        )






        I ran the above code on an Android emulator, I am sure it will work on ios. If there is anything I need to clarify or improve please do tell me






        share|improve this answer














        I am not sure if this is what you are after but the way I did it was nesting two View inside the Animated.View Component which cover the full screen.



        <Animated.View style=[this.position.getLayout(), display: 'flex', flex: 1, flexDirection: 'row'] ...this.panResponder.panHandlers>
        <View style=width: '100%', height: '100%', backgroundColor: 'yellow'>
        <Text>
        This is the Main view
        </Text>
        </View>

        <View style= height: '100%', width: '100%', backgroundColor: 'red'>
        <Text>
        This is the invisible View
        </Text>
        </View>
        </Animated.View>


        • The styling in the Views is to make each cover the full width


        • inside the Animated.View I used the array notation to apply two styles


        • this.position.getLayout() is the one that gives the coordinates/position of where the Animated.View component should be


        • The other styling object is so we can render the child views next to each other using flexbox particularly setting



        • Also attach the panHandlers to the Animated.View



          constructor(props)
          super(props)
          position = new Animated.ValueXY()

          const panResponder = PanResponder.create(
          onStartShouldSetPanResponder: ()=> true,
          onPanResponderMove: (evt, gesture)=>
          //Need to set theshhold and state.isOpen to determine direction here
          position.setValue(x: gesture.dx, y: 0)
          ,
          onPanResponderGrant: ()=>
          this.position.setOffset(x: this.position.x._value, y: 0)
          this.position.setValue(x: 0, y: 0)
          ,
          onPanResponderRelease: ()=>
          this.openOrClose()

          )

          this.state = isOpen: false
          this.panResponder = panResponder
          this.position = position



        • I used state to monitor where the View Should move to this.state = isOpen: false depending on which view was visible.


        • The functions to move are mainly position.setValue(x: gesture.dx, y: 0) which tracks the movement while the touch/pan is still active and this.openOrClose() which is called when the touch/pan is released.


        • The openOrClose function determines how to handle the movement and the main logic should be here. I just did a simple case and did not include any threshHold in this example.


        • To understand panHandlers I suggest you read this article as it explains the reasons for onPanResponderGrant best.


        Below is the code for the working Component






        import React, Component from 'react'
        import View, Text, Animated, PanResponder, Dimensions from 'react-native'

        const ScreenWidth = Dimensions.get('window').width

        //Logic to flattenOffset required
        export class Swipable extends Component
        constructor(props)
        super(props)
        position = new Animated.ValueXY()

        const panResponder = PanResponder.create(
        onStartShouldSetPanResponder: ()=> true,
        onPanResponderMove: (evt, gesture)=>
        //Need to set theshhold and state.isOpen to determine direction here
        position.setValue(x: gesture.dx, y: 0)
        ,
        onPanResponderGrant: ()=>
        this.position.setOffset(x: this.position.x._value, y: 0)
        this.position.setValue(x: 0, y: 0)
        ,
        onPanResponderRelease: ()=>
        this.openOrClose()

        )

        this.state = isOpen: false
        this.panResponder = panResponder
        this.position = position


        openOrClose = ()=>
        this.position.flattenOffset()
        //determine where to move depending onState
        direction = this.state.isOpen ? 0 : -ScreenWidth

        Animated.spring(this.position,
        toValue: x: direction, y: 0
        ).start(()=>
        //Callback when animation is complete to show if open or closed
        this.setState((prevState)=>
        return isOpen: !prevState.isOpen
        )
        )


        render()
        return(
        <Animated.View style=[this.position.getLayout(), display: 'flex', flex: 1, flexDirection: 'row'] ...this.panResponder.panHandlers>
        <View style=width: '100%', height: '100%', backgroundColor: 'yellow'>
        <Text>
        This is the Main view
        </Text>
        </View>

        <View style= height: '100%', width: '100%', backgroundColor: 'red'>
        <Text>
        This is the invisible View
        </Text>
        </View>
        </Animated.View>
        )






        I ran the above code on an Android emulator, I am sure it will work on ios. If there is anything I need to clarify or improve please do tell me






        import React, Component from 'react'
        import View, Text, Animated, PanResponder, Dimensions from 'react-native'

        const ScreenWidth = Dimensions.get('window').width

        //Logic to flattenOffset required
        export class Swipable extends Component
        constructor(props)
        super(props)
        position = new Animated.ValueXY()

        const panResponder = PanResponder.create(
        onStartShouldSetPanResponder: ()=> true,
        onPanResponderMove: (evt, gesture)=>
        //Need to set theshhold and state.isOpen to determine direction here
        position.setValue(x: gesture.dx, y: 0)
        ,
        onPanResponderGrant: ()=>
        this.position.setOffset(x: this.position.x._value, y: 0)
        this.position.setValue(x: 0, y: 0)
        ,
        onPanResponderRelease: ()=>
        this.openOrClose()

        )

        this.state = isOpen: false
        this.panResponder = panResponder
        this.position = position


        openOrClose = ()=>
        this.position.flattenOffset()
        //determine where to move depending onState
        direction = this.state.isOpen ? 0 : -ScreenWidth

        Animated.spring(this.position,
        toValue: x: direction, y: 0
        ).start(()=>
        //Callback when animation is complete to show if open or closed
        this.setState((prevState)=>
        return isOpen: !prevState.isOpen
        )
        )


        render()
        return(
        <Animated.View style=[this.position.getLayout(), display: 'flex', flex: 1, flexDirection: 'row'] ...this.panResponder.panHandlers>
        <View style=width: '100%', height: '100%', backgroundColor: 'yellow'>
        <Text>
        This is the Main view
        </Text>
        </View>

        <View style= height: '100%', width: '100%', backgroundColor: 'red'>
        <Text>
        This is the invisible View
        </Text>
        </View>
        </Animated.View>
        )






        import React, Component from 'react'
        import View, Text, Animated, PanResponder, Dimensions from 'react-native'

        const ScreenWidth = Dimensions.get('window').width

        //Logic to flattenOffset required
        export class Swipable extends Component
        constructor(props)
        super(props)
        position = new Animated.ValueXY()

        const panResponder = PanResponder.create(
        onStartShouldSetPanResponder: ()=> true,
        onPanResponderMove: (evt, gesture)=>
        //Need to set theshhold and state.isOpen to determine direction here
        position.setValue(x: gesture.dx, y: 0)
        ,
        onPanResponderGrant: ()=>
        this.position.setOffset(x: this.position.x._value, y: 0)
        this.position.setValue(x: 0, y: 0)
        ,
        onPanResponderRelease: ()=>
        this.openOrClose()

        )

        this.state = isOpen: false
        this.panResponder = panResponder
        this.position = position


        openOrClose = ()=>
        this.position.flattenOffset()
        //determine where to move depending onState
        direction = this.state.isOpen ? 0 : -ScreenWidth

        Animated.spring(this.position,
        toValue: x: direction, y: 0
        ).start(()=>
        //Callback when animation is complete to show if open or closed
        this.setState((prevState)=>
        return isOpen: !prevState.isOpen
        )
        )


        render()
        return(
        <Animated.View style=[this.position.getLayout(), display: 'flex', flex: 1, flexDirection: 'row'] ...this.panResponder.panHandlers>
        <View style=width: '100%', height: '100%', backgroundColor: 'yellow'>
        <Text>
        This is the Main view
        </Text>
        </View>

        <View style= height: '100%', width: '100%', backgroundColor: 'red'>
        <Text>
        This is the invisible View
        </Text>
        </View>
        </Animated.View>
        )







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 12 at 1:35

























        answered Nov 12 at 1:30









        Craques

        1189




        1189



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53253709%2fhow-do-i-make-a-secondary-view-enter-a-main-view-with-the-panresponder%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Top Tejano songwriter Luis Silva dead of heart attack at 64

            ReactJS Fetched API data displays live - need Data displayed static

            政党