Nested Gesture Navigation Pages and Scrollviews

Hey Guys, I’ve enjoyed learning the past couple days about Fuse and see its great potential in prototyping new interactions. I’m now stumped on an issue of using multiple gesture driven navigation elements to navigate pages and scroll views nested within each other.

The UI is essentially 3 lists all nested within each other. The first is vertical, the next horizontal, and the final another vertical list. I’ve gotten the “Forward” navigation working to dive deeper into each list, but can’t get the gesture driven “Back” navigation working.

I’ve tried to attach a video and the UX Markup to as far as I’ve gotten. Being new at this, maybe I’m structuring something completely wrong or have just overlooked something simple. Can anyone point me in a direction to either restructuring to get the same effect or override a child swipegesture to allow it’s parent’s navigation swipegesture to take control again?

file

<App Theme="Basic">
<iOS.StatusBarConfig Style="Light" IsVisible="false" Animation="Slide"/>


<ClientPanel>
<!--Feed Navigation Level-->
        <Panel ux:Name="Feed">
                <HierarchicalNavigation ux:Name="postToRepliesNavigation" Easing="CubicInOut" />

                <!--List Page-->
                <Page ux:Name="List">
                        <!--List Feed-->
                        <ScrollView>
                                <StackPanel>
                                    <Each Count="5">
                                        <Panel Height="375" Color="Green" Margin="0,20,0,0" >
                                            <SwipeNavigate SwipeDirection="Left" VelocityThreshold="100" />
                                            <Text Alignment="Center">Vertical List 1 Items</Text>
                                        </Panel>
                                    </Each>
                                </StackPanel>
                        </ScrollView>

                        <!--Background-->
                        <Rectangle Color="Gray"/>

                        <!--Page Animations-->
                        <EnteringAnimation>
                                <Move X="-1" RelativeTo="ParentSize" Duration=".5"/>
                        </EnteringAnimation>
                        <ExitingAnimation>
                                <Move X="1" RelativeTo="ParentSize" Duration=".5"/>
                        </ExitingAnimation>
                </Page>

                <!--Replies Page-->
                <Page ux:Name="Replies">

                        <!--Reply Navigation Level-->
                        <PageControl>

                                <!--Reply 1-->
                                <Page ux:Name="Reply1">


                                    <!--Comment Navigation Level-->
                                    <Panel>
                                            <LinearNavigation ux:Name="commentNavigation" Easing="CubicInOut" />
                                            <SwipeNavigate SwipeDirection="Up" VelocityThreshold="100"  />

                                            <Panel ux:Name="replyContent" Background="Red" >
                                            <Text Alignment="Center">Horizontal List Item 1</Text>
                                            <EnteringAnimation>
                                                      <Move Y="-1" RelativeTo="ParentSize"/>
                                            </EnteringAnimation>
                                            <ExitingAnimation>
                                                <Move Y="1" RelativeTo="ParentSize"/>
                                            </ExitingAnimation>
                                            </Panel>

                                            <Panel ux:Name="replyComments" Color="Gray">
                                                            <ScrollView AllowedScrollDirections="Vertical" >
                                                                    <StackPanel>
                                                                            <Each Count="20">
                                                                                    <Panel ux:Name="comments" Color="Blue" Height="100" Margin="0,0,0,10">
                                                                                        <Text Alignment="Center">Vertical List 2 Items</Text>
                                                                                    </Panel>
                                                                            </Each>
                                                                    </StackPanel>
                                                            </ScrollView>

                                                    <!--Page Animations-->
                                            <EnteringAnimation>
                                                      <Move Y="-1" RelativeTo="ParentSize"/>
                                            </EnteringAnimation>
                                            <ExitingAnimation>
                                                <Move Y="1" RelativeTo="ParentSize"/>
                                            </ExitingAnimation>
                                            </Panel>
                                    </Panel>
                                </Page>

                                <!--Reply 2-->
                                <Page ux:Name="Reply2">
                                        <Text Alignment="Center">Horizontal List Item 2</Text>
                                        <Panel Color="Purple"/>
                                </Page>

                                <!--Reply 3-->
                                <Page ux:Name="Reply3">
                                        <Text Alignment="Center">Horizontal List Item 3</Text>
                                        <Panel Color="Green"/>
                                </Page>

                                <!--Reply 4-->
                                <Page ux:Name="Reply4">
                                        <Text Alignment="Center">Horizontal List Item 4</Text>
                                        <Panel Color="Blue"/>
                                </Page>
                        </PageControl>

                        <!--Page Animations-->
                        <EnteringAnimation>
                                <Move X="-1" RelativeTo="ParentSize" Duration=".5"/>
                        </EnteringAnimation>
                        <ExitingAnimation>
                                <Move X="1" RelativeTo="ParentSize" Duration=".5"/>
                        </ExitingAnimation>
                </Page>



        </Panel>
    </ClientPanel>
</App>

Hi Craig!

As far as I understand from your description and code, this is what you want to achieve:

  • List_1(vertical, green) does not consist of pages, but just elements. When you swipe right-to-left to move on to list_2 it doesn’t matter which element in list_1 you’re swiping, we’ll always go to the first entry in list_2 (e.g. the red page)

  • When you’re in list_2 (horizontal) you should only be able to move on to list_3 (by swiping bottom-to-top) when you’re on the first page (red). I.e. swiping bottom-to-top on any other page should do nothing.

  • When you’re in list_3 (vertical, blue) you should not be able to swipe right-to-left and end up on the 2nd element of list_2 ? (This happens in your current code though)

  • And you’d like to move back to earlier lists by swiping in the other direction than what you originally did.

I’d say the main problem here is that you have an entire page of things that can scroll vertically (e.g. list_3) and you also want to navigate vertically to and from that page. It generally seems like a bad idea to mix these interactions as there’s no way of determining when the vertical swipe means scroll and when it means navigate.

To “fix” this I simply added a pink rectangle (representing a point to “grab hold of”) to the top of the page containing list_3. When you swipe at the pink rectangle the page navigates instead of scrolling.

Other changes:

  • Removed some unnecessary navigation (the pagecontrol). List_1 is now simply a page within the same horizontal navigation that constitutes the horizontal list_2
  • Created hPage and vPage to make it easier to deal the enter- and exit-animations for multiple pages
  • Made a toggle (enableHnav) to explicitly control whether you can navigate left-right. This is then used to achieve "when you are inside list_3 (aka the “replyComments” page) you are not allowed to navigate horizontally).
  • Removed some unnecessary pangels and rectangles by setting Color directly on the pages
<App Theme="Basic">
    <iOS.StatusBarConfig Style="Light" IsVisible="false" Animation="Slide"/>

    <ClientPanel>
        <!--Feed Navigation Level-->
        <Panel ux:Name="Feed">
            <HierarchicalNavigation ux:Name="postToRepliesNavigation" Easing="CubicInOut" />

            <WhileTrue ux:Name="enableHnav" Value="true">
                <SwipeNavigate SwipeDirection="Left" VelocityThreshold="100" />
            </WhileTrue>

            <Page ux:Class="hPage">
                <EnteringAnimation>
                    <Move X="-1" RelativeTo="ParentSize" Duration=".5"/>
                </EnteringAnimation>
                <ExitingAnimation>
                    <Move X="1" RelativeTo="ParentSize" Duration=".5"/>
                </ExitingAnimation>
            </Page>
            <Page ux:Class="vPage">
                <EnteringAnimation>
                    <Move Y="-1" RelativeTo="ParentSize"/>
                </EnteringAnimation>
                <ExitingAnimation>
                    <Move Y="1" RelativeTo="ParentSize"/>
                </ExitingAnimation>
            </Page>

            <!--List Page-->
            <hPage ux:Name="List" Color="Gray">
                <!--List Feed-->
                <ScrollView>
                    <StackPanel>
                        <Each Count="5">
                            <Panel Height="375" Color="Green" Margin="0,20,0,0" >
                                <Text Alignment="Center">Vertical List 1 Items</Text>
                            </Panel>
                        </Each>
                    </StackPanel>
                </ScrollView>
            </hPage>

            <!--Reply 1-->
            <hPage ux:Name="Reply1">
                <Panel>
                    <LinearNavigation ux:Name="commentNavigation" Easing="CubicInOut" />
                    <SwipeNavigate SwipeDirection="Up" VelocityThreshold="100"  />

                    <vPage ux:Name="replyContent" Color="Red" >
                        <Text Alignment="Center">Horizontal List Item 1</Text>
                    </vPage>

                    <vPage ux:Name="replyComments" Color="Gray">
                        <WhileActive>
                            <Change enableHnav.Value="false"/>
                        </WhileActive>
                        <DockPanel>
                            <Rectangle Color="#f0f" Height="10%" Dock="Top"/>
                            <ScrollView AllowedScrollDirections="Vertical">
                                <StackPanel>
                                    <Each Count="20">
                                        <Panel ux:Name="comments" Color="Blue" Height="100" Margin="0,0,0,10">
                                            <Text Alignment="Center">Vertical List 2 Items</Text>
                                        </Panel>
                                    </Each>
                                </StackPanel>
                            </ScrollView>
                        </DockPanel>
                    </vPage>
                </Panel>
            </hPage>

            <!--Reply 2-->
            <hPage ux:Name="Reply2" Color="Purple">
                <Text Alignment="Center">Horizontal List Item 2</Text>
            </hPage>

            <!--Reply 3-->
            <hPage ux:Name="Reply3" Color="Green">
                <Text Alignment="Center">Horizontal List Item 3</Text>
            </hPage>

        </Panel>
    </ClientPanel>
</App>

Hey Remi! Thanks for the detailed reply. I suppose I should have clarified my goals much better.

  • Each of the green items in the first vertical list_1 will have different content. Upon swiping (right to left) over an individual green item (and only the green items) I want it to pull in the full page horizontal list_2 items. I haven’t figured out how to make this work yet, but each green item would ideally have it’s own associated horizontal list content associated with it. For now I was just taking baby steps to figure out the gesture navigation.

When you’re in list_2 (horizontal) you should only be able to move on to list_3 (by swiping bottom-to-top) when you’re on the first page (red). I.e. swiping bottom-to-top on any other page should do nothing.

  • Sorry for the confusion. I haven’t yet added them in, but each list_2 (horizontal) item will have its own list_3 that can be accessed by swiping bottom-to-top.

So the overall structure looks a lot like this: (Upload rotated the image 90degress for some reason)

When you’re in list_3 (vertical, blue) you should not be able to swipe right-to-left and end up on the 2nd element of list_2 ? (This happens in your current code though)

  • When I’m in list_3, I do indeed want to be able to move horizontally between each list_2 item. A good example of this interaction is actually already built in Snapchat’s Discover section where it has company publications. Inside a company’s Publication/Story there is a horizontal list of content and you can swipe bottom-to-top to access a scrollview beneath. You can then swipe right-to-left to access the next

And you’d like to move back to earlier lists by swiping in the other direction than what you originally did.

  • This is correct.

The pink bar that you placed in list_3 definitely works, but I was hoping to be able to trigger a swipegesture (top-to-bottom) to navigate back to list_2 when the scrollview is at rest at the top of the list much like the interaction you can see in Snapchat’s Discover sections.

file

Does this make more sense? I believe my goal is to see if there is some way to override which gesture driven UI element is being effected by a swipeing gesture at various times. I tried for a bit to use ‘WhileScrollable’ to trigger some kind of override of the scrollview vertical gesture back to that of the vertical ‘SwipeNavigate’

Thanks for the clarifications. :slight_smile:

There are two things we need to solve then:

  1. Have different “sub-lists” depending on which parent you’re navigating from.
  2. Handle the switch from scrolling to navigation at the top of list_3.

The first one should be much easier once we get the new navigation functionality out, but I think it should be possible now as well (without having to manually create a ton of lists, of course). I’ll have a look at it asap.

The second one I’m slightly less sure about. I’ll have a chat with our Gesture Experts ™ and see what they come up with. Of course, in the extreme case most things can be solved with custom Uno code but let’s see if we can do without. :slight_smile:

So, after some internal discussion it turns out there’s currently no way of seamlessly switching from scrolling to navigation as described above. We’ve made a ticket to look into that functionality at some point, but it may be a while before we have time to do it.

I’ve come up with something that can hopefully serve as a workaround for now:

<App Theme="Basic">
    <ClientPanel>
        <Page ux:Class="vPage">
            <EnteringAnimation>
                <Move Y="-1" RelativeTo="ParentSize"/>
            </EnteringAnimation>
            <ExitingAnimation>
                <Move Y="1" RelativeTo="ParentSize"/>
            </ExitingAnimation>
        </Page>

        <Panel ux:Name="container">
            <LinearNavigation ux:Name="commentNavigation" Easing="CubicInOut" />
            <SwipeNavigate SwipeDirection="Up" VelocityThreshold="100" />

            <vPage ux:Name="replyContent" Color="Red" >
                <WhileActive>
                    <Set pullTxt.Value="Pull up"/>
                </WhileActive>
                <Text Alignment="Center">Horizontal List Item 1</Text>
                <Text ux:Name="pullTxt" Alignment="BottomCenter"/>
            </vPage>

            <vPage ux:Name="replyComments" Color="Gray">
                <WhileActive>
                    <Set pullTxt.Value="Pull Down"/>
                </WhileActive>
                <ScrollView ux:Name="sv" SnapMinTransform="false" >
                    <ScrollingAnimation Range="SnapMin">
                        <Set commentNavigation.Active="replyContent" AtProgress="0.7" />
                        <Move Target="container" Y="0.3" RelativeTo="Size"/>
                    </ScrollingAnimation>

                    <StackPanel>
                        <Each Count="20">
                            <Panel ux:Name="comments" Color="Blue" Height="100" Margin="0,0,0,10">
                                <Text Alignment="Center">Vertical List 2 Items</Text>
                            </Panel>
                        </Each>
                    </StackPanel>
                </ScrollView>
            </vPage>
        </Panel>
    </ClientPanel>
</App>

The key here is the ScrollingAnimation which takes effect when you scroll past the top of the ScrollView (e.g. when it’s in the SnapMin range). At that point it begins to move the entire navigator (the “container” Panel) downwards, until it reaches a pre-defined point and triggers a navigation back to the red page. (The downwards movement that would normally affect just the scrollview has been disabled with SnapMinTransform="false".)

It’s basically the same mechanism used in the pull-to-reload example.

Awesome, that works a bit better than the solution that I came up with.

Thanks Remi!