/// <summary> /// Update headers and navigation bar translation Y by scroll /// </summary> private static void HandleScrolling(HeaderLayout headerLayout, ContentPage contentPage, NavigationPage navigationPage, double oldScrollY, double newScrollY) { // Save previous scroll Y if (headerLayout != null) { headerLayout.ScrollY = newScrollY; } TryGetNavigationBarProperties(contentPage, navigationPage, out double navigationBarHeight, out double navigationBarY, out bool isNavigationBarFloating, out bool isNavigationBarScrollable); // Scroll delta double delta = Math.Max(0, newScrollY) - Math.Max(0, oldScrollY); // Update navigation bar translation when it should scroll out smoothly or not if (navigationPage != null && contentPage != null && (NavigationBar.GetVisibility(contentPage) == NavigationBarVisibility.Scroll || NavigationBar.GetVisibility(contentPage) == NavigationBarVisibility.SmoothScroll)) { View navigationBar = navigationPage.GetNavigationBar(); // Hide navigation bar smoothly if (NavigationBar.GetVisibility(contentPage) == NavigationBarVisibility.SmoothScroll && navigationBar != null) { // If scrolled enought speed do smooth navigation bar hiding with animation if (Math.Abs(delta) > 5) { string showScrollBarAnimationName = "showScrollBarAnimation"; string hideScrollBarAnimationName = "hideScrollBarAnimation"; double start = navigationBar.TranslationY; double target = 0; string actualAnimationName; if (delta < 0) { target = 0; actualAnimationName = showScrollBarAnimationName; } else { target = -navigationBarHeight + RootPage.Instance.SafeAreaInsest.Top; actualAnimationName = hideScrollBarAnimationName; } if (target != navigationBar.TranslationY && AnimationExtensions.AnimationIsRunning(navigationBar, actualAnimationName) == false) { AnimationExtensions.AbortAnimation(navigationBar, showScrollBarAnimationName); AnimationExtensions.AbortAnimation(navigationBar, hideScrollBarAnimationName); new Animation(d => { // Animate NavigastionBar TranslationY navigationBar.TranslationY = start + (target - start) * d; // Get NavigationBar properties during animation because they can change TryGetNavigationBarProperties(contentPage, navigationPage, out navigationBarHeight, out navigationBarY, out isNavigationBarFloating, out isNavigationBarScrollable); // Update headers transaltion because navigation bar translation is animated headerLayout?.UpdateHeadersTranslationY(headerLayout.ScrollY, navigationBarHeight, navigationBarY, isNavigationBarFloating, isNavigationBarScrollable); }, 0, 1).Commit(navigationBar, actualAnimationName, 64, 250); } else { headerLayout?.UpdateHeadersTranslationY(newScrollY, navigationBarHeight, navigationBar.TranslationY, isNavigationBarFloating, isNavigationBarScrollable); } } // If not scrolled enought speed, then hide other headers normally else { headerLayout?.UpdateHeadersTranslationY(newScrollY, navigationBarHeight, navigationBar.TranslationY, isNavigationBarFloating, isNavigationBarScrollable); } } // Hide navigation bar based on scroll only else { navigationBar.TranslationY = Math.Min(0, Math.Max(-navigationBarHeight + RootPage.Instance.SafeAreaInsest.Top, navigationBar.TranslationY - delta)); navigationBarY = navigationBar.TranslationY; headerLayout?.UpdateHeadersTranslationY(newScrollY, navigationBarHeight, navigationBarY, isNavigationBarFloating, isNavigationBarScrollable); } } // If navigation bar is visible or hidden else { headerLayout?.UpdateHeadersTranslationY(newScrollY, navigationBarHeight, navigationBarY, isNavigationBarFloating, isNavigationBarScrollable); } }