Skip to content

Commit

Permalink
Ensure last breadcrumb is always visible and always animates in (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
IeuanWalker authored Nov 28, 2024
1 parent 45bba53 commit 7871436
Showing 1 changed file with 45 additions and 12 deletions.
57 changes: 45 additions & 12 deletions Scr/Breadcrumb.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,13 @@ async void BreadCrumbContainer_Loaded(object? sender, EventArgs e)
continue;
}

Border invisibleBreadcrumb = BreadcrumbCreator(page, page.Equals(pages.LastOrDefault()), page.Equals(pages.FirstOrDefault()));
invisibleBreadcrumb.Opacity = 0;
AutomationProperties.SetIsInAccessibleTree(invisibleBreadcrumb, false);
AutomationProperties.SetExcludedWithChildren(invisibleBreadcrumb, true);

BreadCrumbContainer.Children.Add(invisibleBreadcrumb);

if(BreadCrumbContainer.Children.Count > 0)
{
await BreadCrumbsScrollView.ScrollToAsync((View?)BreadCrumbContainer.Children.LastOrDefault(), ScrollToPosition.MakeVisible, false);
Expand All @@ -195,7 +202,7 @@ async void BreadCrumbContainer_Loaded(object? sender, EventArgs e)
breadcrumb.TranslationX = Application.Current?.Windows[0].Page?.Width ?? 0;

// Scroll to end of control
await Task.Delay(10);
await Task.Delay(100);

// HACK: Remove once fixed - https://github.com/dotnet/maui/issues/9446
if(BreadCrumbContainer.Width < BreadCrumbsScrollView.Width)
Expand Down Expand Up @@ -268,21 +275,47 @@ Border BreadcrumbCreator(Page page, bool isLast, bool isFirst)
/// </summary>
async void AnimatedStack_ChildAdded(object? sender, ElementEventArgs e)
{
// iOS scroll to end fix
if(DeviceInfo.Platform.Equals(DevicePlatform.iOS))
await Task.Run(async () =>
{
await BreadCrumbsScrollView.ScrollToAsync((View?)BreadCrumbContainer.Children.LastOrDefault(), ScrollToPosition.MakeVisible, false);
}
while(BreadCrumbContainer.Children.LastOrDefault() is not View lastBreadcrumb || lastBreadcrumb.Width <= 0)
{
await Task.Delay(100);
}

Animation lastBreadcrumbAnimation = new()
{
{ 0, 1, new Animation(_ => ((View)BreadCrumbContainer.Children[^1]).TranslationX = _, Application.Current?.Windows[0].Page?.Width ?? 0, 0, Easing.Linear) }
};
// iOS scroll to end fix
if(DeviceInfo.Platform.Equals(DevicePlatform.iOS))
{
MainThread.BeginInvokeOnMainThread(async () => await BreadCrumbsScrollView.ScrollToAsync((View?)BreadCrumbContainer.Children.LastOrDefault(), ScrollToPosition.MakeVisible, false));
}

double lastBreadcrumbWidth = ((View)BreadCrumbContainer.Children[^1]).Width;
Animation lastBreadcrumbAnimation = new()
{
{ 0, 1, new Animation(_ => ((View)BreadCrumbContainer.Children[^1]).TranslationX = _, Application.Current?.Windows[0].Page?.Width - lastBreadcrumbWidth ?? 0, lastBreadcrumbWidth * -1, Easing.Linear) }
};

Point point = BreadCrumbsScrollView.GetScrollPositionForElement((View)BreadCrumbContainer.Children[^1], ScrollToPosition.End);
lastBreadcrumbAnimation.Add(0, 1, new Animation(_ => BreadCrumbsScrollView.ScrollToAsync((View?)BreadCrumbContainer.Children.LastOrDefault(), ScrollToPosition.MakeVisible, true), BreadCrumbsScrollView.X, point.X - 6));

Point point = BreadCrumbsScrollView.GetScrollPositionForElement((View)BreadCrumbContainer.Children[^1], ScrollToPosition.End);
lastBreadcrumbAnimation.Add(0, 1, new Animation(_ => BreadCrumbsScrollView.ScrollToAsync((View?)BreadCrumbContainer.Children.LastOrDefault(), ScrollToPosition.MakeVisible, true), BreadCrumbsScrollView.X, point.X - 6));
MainThread.BeginInvokeOnMainThread(() => lastBreadcrumbAnimation.Commit(this, nameof(lastBreadcrumbAnimation), 16, AnimationSpeed));

double containerWidth = 0;
foreach(View view in BreadCrumbContainer.Children.Cast<View>())
{
containerWidth += view.Width;
}
containerWidth -= lastBreadcrumbWidth;

lastBreadcrumbAnimation.Commit(this, nameof(lastBreadcrumbAnimation), 16, AnimationSpeed);
if(containerWidth > BreadCrumbsScrollView.Width)
{
MainThread.BeginInvokeOnMainThread(() => BreadCrumbContainer.WidthRequest = containerWidth);
}
else
{
MainThread.BeginInvokeOnMainThread(() => BreadCrumbContainer.WidthRequest = BreadCrumbsScrollView.Width);
}
MainThread.BeginInvokeOnMainThread(async () => await BreadCrumbsScrollView.ScrollToAsync((View?)BreadCrumbContainer.Children.LastOrDefault(), ScrollToPosition.MakeVisible, false));
});
}

/// <summary>
Expand Down

0 comments on commit 7871436

Please sign in to comment.