Skip to content
This repository was archived by the owner on May 1, 2024. It is now read-only.

Commit 156c7b6

Browse files
sanyandreichukrmarinho
authored andcommitted
Fix ScrollTo on Mac (#4983) * fixes #3319
* Fix github issue #3319 Fix #3319 [MAC] ScrollTo method is not working in Xamarin.Forms for mac platform * Update Issue3318.cs Fix Issue3318 UITest. * Fix github issue #3319 Fix #3319 [MAC] ScrollTo method is not working in Xamarin.Forms for mac platform * Update Issue3318.cs Fix Issue3318 UITest.
1 parent 88fbd3b commit 156c7b6

File tree

3 files changed

+146
-2
lines changed

3 files changed

+146
-2
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Collections.ObjectModel;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using System.Linq;
7+
using Xamarin.Forms.CustomAttributes;
8+
using Xamarin.Forms.Internals;
9+
10+
11+
#if UITEST
12+
using Xamarin.UITest;
13+
using NUnit.Framework;
14+
using Xamarin.Forms.Core.UITests;
15+
#endif
16+
17+
namespace Xamarin.Forms.Controls.Issues
18+
{
19+
[Preserve(AllMembers = true)]
20+
[Issue(IssueTracker.Github, 3318, "[MAC] ScrollTo method is not working in Xamarin.Forms for mac platform", PlatformAffected.macOS)]
21+
22+
public class Issue3318 : TestContentPage
23+
{
24+
protected override void Init()
25+
{
26+
var stackLayout = new StackLayout();
27+
28+
var list = Enumerable.Range(0, 40).Select(c => $"Item {c}").ToArray();
29+
var listview = new ListView { ItemsSource = list };
30+
31+
var swShouldAnimate = new Switch();
32+
var lblShouldAnimate = new Label { Text = "Should Animate?" };
33+
34+
var btnMakeVisible = new Button { Text = "Make Visible" };
35+
btnMakeVisible.Clicked += (s, e) =>
36+
{
37+
listview.ScrollTo(list[19], ScrollToPosition.MakeVisible, swShouldAnimate.IsToggled);
38+
};
39+
40+
var btnCenter = new Button { Text = "Center" };
41+
btnCenter.Clicked += (s, e) =>
42+
{
43+
listview.ScrollTo(list[19], ScrollToPosition.Center, swShouldAnimate.IsToggled);
44+
};
45+
46+
var btnStart = new Button { Text = "Start" };
47+
btnStart.Clicked += (s, e) =>
48+
{
49+
listview.ScrollTo(list[19], ScrollToPosition.Start, swShouldAnimate.IsToggled);
50+
};
51+
52+
var btnEnd = new Button { Text = "End" };
53+
btnEnd.Clicked += (s, e) =>
54+
{
55+
listview.ScrollTo(list[19], ScrollToPosition.End, swShouldAnimate.IsToggled);
56+
};
57+
58+
stackLayout.Children.Add(btnMakeVisible);
59+
stackLayout.Children.Add(btnCenter);
60+
stackLayout.Children.Add(btnStart);
61+
stackLayout.Children.Add(btnEnd);
62+
63+
var shouldAnimateContainer = new StackLayout { Orientation = StackOrientation.Horizontal };
64+
shouldAnimateContainer.Children.Add(swShouldAnimate);
65+
shouldAnimateContainer.Children.Add(lblShouldAnimate);
66+
67+
stackLayout.Children.Add(shouldAnimateContainer);
68+
stackLayout.Children.Add(listview);
69+
70+
Content = stackLayout;
71+
}
72+
73+
74+
#if UITEST
75+
[Test]
76+
public void Issue3318Test()
77+
{
78+
RunningApp.WaitForElement (q => q.Marked ("End"));
79+
RunningApp.Tap (q => q.Marked ("End"));
80+
RunningApp.WaitForElement (q => q.Marked ("Item 19"));
81+
RunningApp.Back ();
82+
}
83+
#endif
84+
}
85+
}

Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,7 @@
877877
<Compile Include="$(MSBuildThisFileDirectory)Issue3622.cs" />
878878
<Compile Include="$(MSBuildThisFileDirectory)Issue4138.cs" />
879879
<Compile Include="$(MSBuildThisFileDirectory)Issue4314.cs" />
880+
<Compile Include="$(MSBuildThisFileDirectory)Issue3318.cs" />
880881
</ItemGroup>
881882
<ItemGroup>
882883
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Bugzilla22229.xaml">

Xamarin.Forms.Platform.MacOS/Renderers/ListViewRenderer.cs

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Generic;
23
using System.Collections.Specialized;
34
using System.ComponentModel;
45
using System.Linq;
@@ -346,9 +347,66 @@ void UpdateSeparatorVisibility()
346347
{
347348
}
348349

349-
//TODO: Implement ScrollTo
350350
void OnScrollToRequested(object sender, ScrollToRequestedEventArgs e)
351351
{
352+
var templatedItems = TemplatedItemsView.TemplatedItems;
353+
var scrollArgs = (ITemplatedItemsListScrollToRequestedEventArgs)e;
354+
355+
var row = templatedItems?.GetGlobalIndexOfItem(scrollArgs.Item) ?? -1;
356+
if (row == -1)
357+
return;
358+
359+
var rowRect = _table.RectForRow(row);
360+
var rowHeight = rowRect.Height;
361+
var clipView = _table.Superview as NSClipView;
362+
var clipViewHeight = clipView.Frame.Height;
363+
var scrollToPosition = e.Position;
364+
365+
if (scrollToPosition == ScrollToPosition.MakeVisible)
366+
{
367+
var topVisibleY = clipView.Bounds.Y;
368+
var bottomVisibleY = clipView.Bounds.Y + clipViewHeight - rowHeight;
369+
370+
if (topVisibleY > rowRect.Y)
371+
{
372+
scrollToPosition = ScrollToPosition.Start;
373+
}
374+
else if (bottomVisibleY < rowRect.Y)
375+
{
376+
scrollToPosition = ScrollToPosition.End;
377+
}
378+
else
379+
{
380+
return;
381+
}
382+
}
383+
384+
nfloat y = 0;
385+
var scrollOrigin = rowRect.Location;
386+
387+
if (scrollToPosition == ScrollToPosition.Center)
388+
{
389+
y = (scrollOrigin.Y - clipViewHeight / 2) + rowHeight / 2;
390+
}
391+
else if (scrollToPosition == ScrollToPosition.End)
392+
{
393+
y = scrollOrigin.Y - clipViewHeight + rowHeight;
394+
}
395+
else
396+
{
397+
y = scrollOrigin.Y;
398+
}
399+
400+
scrollOrigin.Y = y;
401+
402+
if (e.ShouldAnimate)
403+
{
404+
((NSView)clipView.Animator).SetBoundsOrigin(scrollOrigin);
405+
}
406+
else
407+
{
408+
clipView.SetBoundsOrigin(scrollOrigin);
409+
}
352410
}
353411

354412
//TODO: Implement Footer

0 commit comments

Comments
 (0)