Adding a swipe gesture to open SplitView Pane

后端 未结 2 1459
眼角桃花
眼角桃花 2020-12-02 07:58

I am trying to add a swipe gesture to the SplitView control (aka \"hamburger menu\") of UWP, similar to the swipe left/right of a Pivot control. How can I set a gesture to c

2条回答
  •  谎友^
    谎友^ (楼主)
    2020-12-02 08:51

    Interesting question! :)

    I recently created a SwipeableSplitView which extends the SplitView control to enable a swipe from left edge gesture when the DisplayMode is set to Overlay (as I don't see the point to have it in other modes, but feel free to extend it whenever needed).

    All I am doing is, inside the control's style, create another layer on top of the PaneRoot layer and handle all the gestures there.

    
        
            
                
                    
                
            
        
        
            
        
        
        
    
    
    
    
        
            
            
            
        
        
        
            
                
            
        
        
        
    
    

    While updating the TranslateX of the new layer's transform object, I am also updating the PaneRoot's to keep their position in sync.

    void OnManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
    {
        _panAreaTransform = PanArea.RenderTransform as CompositeTransform;
        _paneRootTransform = PaneRoot.RenderTransform as CompositeTransform;
    
        if (_panAreaTransform == null || _paneRootTransform == null)
        {
            throw new ArgumentException("Make sure you have copied the default style to Generic.xaml!!");
        }
    }
    
    void OnManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
    {
        var x = _panAreaTransform.TranslateX + e.Delta.Translation.X;
    
        // keep the pan within the bountry
        if (x < PanAreaInitialTranslateX || x > 0) return;
    
        // while we are panning the PanArea on X axis, let's sync the PaneRoot's position X too
        _paneRootTransform.TranslateX = _panAreaTransform.TranslateX = x;
    }
    
    void OnManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
    {
        var x = e.Velocities.Linear.X;
    
        // ignore a little bit velocity (+/-0.1)
        if (x <= -0.1)
        {
            CloseSwipeablePane();
        }
        else if (x > -0.1 && x < 0.1)
        {
            if (Math.Abs(_panAreaTransform.TranslateX) > Math.Abs(PanAreaInitialTranslateX) / 2)
            {
                CloseSwipeablePane();
            }
            else
            {
                OpenSwipeablePane();
            }
        }
        else
        {
            OpenSwipeablePane();
        }
    }
    

    Keep in mind that because the IsPaneOpen property is not virtual, I have to create another one IsSwipeablePaneOpen to wrap the former around. So whenever you feel like using the IsPaneOpen property, use IsSwipeablePaneOpen instead.

    This is how it works in a demo app I created in GitHub. You can find the full source code here.


    Credits

    • The SplitView template was generated from Koen Zwikstra's awesome Visual Studio UWP templates.
    • Page animations and some other implementations were inspired by this post from Jerry Nixon.

提交回复
热议问题