Search code examples
xamarin.iosuiscrollviewparallax

adding a parallax effect on scroll


I have a view that has a scrollview and a regular view on top, right now it just changes of the layer elevation so that when the scrollview is being dragged down it makes it topmost.

I'd like to do one better and add a nice fading effect but currently I'm having trouble making it fade smoothly.

here is what I'm currently doing:

private void MainScrollViewOnScrolled(object sender, EventArgs e)
{
    if (!(sender is UIScrollView scrollView))
    {
        return;
    }

    var topViewHeight = vTopPanel.Bounds.Height;
    var scrollOffsetY = scrollView.ContentOffset.Y;

    var scrollIndicatorInsets = scrollView.ScrollIndicatorInsets;

    nfloat scrollIndicatorTop = 0;
    var scrollOffsetDelta = topViewHeight - scrollOffsetY;

    if (scrollOffsetDelta > 0)
    {
        scrollIndicatorTop = scrollOffsetDelta;
    }

    scrollIndicatorInsets.Top = scrollIndicatorTop;
    scrollView.ScrollIndicatorInsets = scrollIndicatorInsets;

    var generalInfoEnabled = scrollOffsetY == 0;

    if (generalInfoEnabled)
    {
        vTopPanel.Alpha = 0;
        vTopPanel.Transform = CGAffineTransform.MakeIdentity();
        UIView.Animate(0.3f, 0, UIViewAnimationOptions.CurveEaseInOut,
            () => {
                vTopPanel.Alpha = 1;
            },
            null
        );
    }
    else
    {
        vTopPanel.Alpha = 1;
        vTopPanel.Transform = CGAffineTransform.MakeIdentity();
        UIView.Animate(0.3f, 0, UIViewAnimationOptions.CurveEaseInOut,
            () => {
                vTopPanel.Alpha = 0;
            },
            null
        );
    }
}

it works, but not very well, when I drag down it fades away but when I scroll back to the top there's a noticeable delay of when the top view reappears. Android has a really nice way of doing the parallax effect, hoping someone can steer me in the right way to do it for iOS.


Solution

  • You can change the vTopPanel.Alpha along with the scrollOffsetY. And make it visable or not visable through the value of scrollOffsetY.

    For example:

        private void MainScrollViewOnScrolled(object sender, EventArgs e)
        {
            if (!(sender is UIScrollView scrollView))
            {
                return;
            }
    
            var topViewHeight = vTopPanel.Bounds.Height;
            var scrollOffsetY = scrollView.ContentOffset.Y;
    
            var scrollIndicatorInsets = scrollView.ScrollIndicatorInsets;
    
            nfloat scrollIndicatorTop = 0;
            var scrollOffsetDelta = topViewHeight - scrollOffsetY;
    
            if (scrollOffsetDelta > 0)
            {
                scrollIndicatorTop = scrollOffsetDelta;
            }
    
            scrollIndicatorInsets.Top = scrollIndicatorTop;
            scrollView.ScrollIndicatorInsets = scrollIndicatorInsets;
    
            //you can custom the topViewAlpha  here 
            //nfloat topViewAlpha = scrollOffsetY / (this.View.Frame.Height -vTopPanel.Frame.Size.Height);
    
            nfloat topViewAlpha = scrollOffsetY / (vTopPanel.Frame.Size.Height);
    
            if (topViewAlpha >=1)
            {
                topViewAlpha = 1;
            }
    
            //To get the opposite effect
            topViewAlpha = 1 - topViewAlpha;
    
    
            vTopPanel.Alpha = topViewAlpha;
        }
    }