Skip to content

Commit 7871436

Browse files
authored
Ensure last breadcrumb is always visible and always animates in (#18)
1 parent 45bba53 commit 7871436

File tree

1 file changed

+45
-12
lines changed

1 file changed

+45
-12
lines changed

Scr/Breadcrumb.xaml.cs

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,13 @@ async void BreadCrumbContainer_Loaded(object? sender, EventArgs e)
183183
continue;
184184
}
185185

186+
Border invisibleBreadcrumb = BreadcrumbCreator(page, page.Equals(pages.LastOrDefault()), page.Equals(pages.FirstOrDefault()));
187+
invisibleBreadcrumb.Opacity = 0;
188+
AutomationProperties.SetIsInAccessibleTree(invisibleBreadcrumb, false);
189+
AutomationProperties.SetExcludedWithChildren(invisibleBreadcrumb, true);
190+
191+
BreadCrumbContainer.Children.Add(invisibleBreadcrumb);
192+
186193
if(BreadCrumbContainer.Children.Count > 0)
187194
{
188195
await BreadCrumbsScrollView.ScrollToAsync((View?)BreadCrumbContainer.Children.LastOrDefault(), ScrollToPosition.MakeVisible, false);
@@ -195,7 +202,7 @@ async void BreadCrumbContainer_Loaded(object? sender, EventArgs e)
195202
breadcrumb.TranslationX = Application.Current?.Windows[0].Page?.Width ?? 0;
196203

197204
// Scroll to end of control
198-
await Task.Delay(10);
205+
await Task.Delay(100);
199206

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

277-
Animation lastBreadcrumbAnimation = new()
278-
{
279-
{ 0, 1, new Animation(_ => ((View)BreadCrumbContainer.Children[^1]).TranslationX = _, Application.Current?.Windows[0].Page?.Width ?? 0, 0, Easing.Linear) }
280-
};
285+
// iOS scroll to end fix
286+
if(DeviceInfo.Platform.Equals(DevicePlatform.iOS))
287+
{
288+
MainThread.BeginInvokeOnMainThread(async () => await BreadCrumbsScrollView.ScrollToAsync((View?)BreadCrumbContainer.Children.LastOrDefault(), ScrollToPosition.MakeVisible, false));
289+
}
290+
291+
double lastBreadcrumbWidth = ((View)BreadCrumbContainer.Children[^1]).Width;
292+
Animation lastBreadcrumbAnimation = new()
293+
{
294+
{ 0, 1, new Animation(_ => ((View)BreadCrumbContainer.Children[^1]).TranslationX = _, Application.Current?.Windows[0].Page?.Width - lastBreadcrumbWidth ?? 0, lastBreadcrumbWidth * -1, Easing.Linear) }
295+
};
296+
297+
Point point = BreadCrumbsScrollView.GetScrollPositionForElement((View)BreadCrumbContainer.Children[^1], ScrollToPosition.End);
298+
lastBreadcrumbAnimation.Add(0, 1, new Animation(_ => BreadCrumbsScrollView.ScrollToAsync((View?)BreadCrumbContainer.Children.LastOrDefault(), ScrollToPosition.MakeVisible, true), BreadCrumbsScrollView.X, point.X - 6));
281299

282-
Point point = BreadCrumbsScrollView.GetScrollPositionForElement((View)BreadCrumbContainer.Children[^1], ScrollToPosition.End);
283-
lastBreadcrumbAnimation.Add(0, 1, new Animation(_ => BreadCrumbsScrollView.ScrollToAsync((View?)BreadCrumbContainer.Children.LastOrDefault(), ScrollToPosition.MakeVisible, true), BreadCrumbsScrollView.X, point.X - 6));
300+
MainThread.BeginInvokeOnMainThread(() => lastBreadcrumbAnimation.Commit(this, nameof(lastBreadcrumbAnimation), 16, AnimationSpeed));
301+
302+
double containerWidth = 0;
303+
foreach(View view in BreadCrumbContainer.Children.Cast<View>())
304+
{
305+
containerWidth += view.Width;
306+
}
307+
containerWidth -= lastBreadcrumbWidth;
284308

285-
lastBreadcrumbAnimation.Commit(this, nameof(lastBreadcrumbAnimation), 16, AnimationSpeed);
309+
if(containerWidth > BreadCrumbsScrollView.Width)
310+
{
311+
MainThread.BeginInvokeOnMainThread(() => BreadCrumbContainer.WidthRequest = containerWidth);
312+
}
313+
else
314+
{
315+
MainThread.BeginInvokeOnMainThread(() => BreadCrumbContainer.WidthRequest = BreadCrumbsScrollView.Width);
316+
}
317+
MainThread.BeginInvokeOnMainThread(async () => await BreadCrumbsScrollView.ScrollToAsync((View?)BreadCrumbContainer.Children.LastOrDefault(), ScrollToPosition.MakeVisible, false));
318+
});
286319
}
287320

288321
/// <summary>

0 commit comments

Comments
 (0)