From 8da3ccf8e8a2b36c90d257b8216f289707ac8544 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Javier=20Su=C3=A1rez=20Ruiz?= Date: Tue, 15 Oct 2019 16:37:41 +0200 Subject: [PATCH] Fixed issue setting Position in CarouselView (#7901) fixes #7865 * Added sample file * Updated sample * Fixed the issue on Android and iOS * Updated IsScrolling property from UWP CarouselView renderer * Added repro sample instructions * Update Issue7865.xaml.cs * [iOS] Update IsScrolling from renderer --- .../Issue7865.xaml | 113 +++++++++++++++++++ .../Issue7865.xaml.cs | 123 +++++++++++++++++++++ .../Xamarin.Forms.Controls.Issues.Shared.projitems | 12 +- Xamarin.Forms.Core/Items/CarouselView.cs | 7 +- .../CollectionView/CarouselViewRenderer.cs | 2 + .../CollectionView/CarouselViewRenderer.cs | 2 + .../CollectionView/CarouselViewController.cs | 5 + .../CollectionView/CarouselViewDelegator.cs | 17 +++ 8 files changed, 277 insertions(+), 4 deletions(-) create mode 100644 Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue7865.xaml create mode 100644 Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue7865.xaml.cs diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue7865.xaml b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue7865.xaml new file mode 100644 index 0000000..9e425f4 --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue7865.xaml @@ -0,0 +1,113 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue7865.xaml.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue7865.xaml.cs new file mode 100644 index 0000000..50a33eb --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue7865.xaml.cs @@ -0,0 +1,123 @@ +using Xamarin.Forms.Internals; +using Xamarin.Forms.CustomAttributes; +using System.Collections.ObjectModel; +using Xamarin.Forms.Xaml; +using System.Collections.Generic; + +#if UITEST +using Xamarin.UITest; +using Xamarin.UITest.Queries; +using NUnit.Framework; +using Xamarin.Forms.Core.UITests; +#endif + +namespace Xamarin.Forms.Controls.Issues +{ +#if UITEST + [Category(UITestCategories.CarouselView)] +#endif +#if APP + [XamlCompilation(XamlCompilationOptions.Compile)] +#endif + [Preserve(AllMembers = true)] + [Issue(IssueTracker.Github, 7865, "[iOS] CarouselView setting Position has dif behavior than ScrollTo", PlatformAffected.iOS)] + public partial class Issue7865 : TestContentPage + { + public Issue7865() + { +#if APP + Device.SetFlags(new List { CollectionView.CollectionViewExperimental }); + Title = "Issue 7865"; + InitializeComponent(); +#endif + } + + protected override void Init() + { + BindingContext = new Issue7865ViewModel(); + } + + public void OnPositionChanged(object sender, PositionChangedEventArgs args) + { +#if APP + IndicatorView.SelectedItem = (BindingContext as Issue7865ViewModel).Monkeys[args.CurrentPosition]; +#endif + } + + public void IndicatorSelectionChanged(object sender, SelectionChangedEventArgs args) + { +#if APP + ItemsCarousel.Position = (BindingContext as Issue7865ViewModel).Monkeys.IndexOf(args.CurrentSelection[0] as Issue7865Model); +#endif + } + } + + [Preserve(AllMembers = true)] + public class Issue7865Model + { + public int Index { get; set; } + public string Name { get; set; } + public string Location { get; set; } + public string Details { get; set; } + public string ImageUrl { get; set; } + } + + [Preserve(AllMembers = true)] + public class Issue7865ViewModel : BindableObject + { + public Issue7865ViewModel() + { + CreateItems(); + } + + public ObservableCollection Monkeys { get; private set; } = new ObservableCollection(); + + public void CreateItems() + { + Monkeys.Add(new Issue7865Model + { + Index = 0, + Name = "Baboon", + Location = "Africa & Asia", + Details = "Baboons are African and Arabian Old World monkeys belonging to the genus Papio, part of the subfamily Cercopithecinae.", + ImageUrl = "http://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg" + }); + + Monkeys.Add(new Issue7865Model + { + Index = 1, + Name = "Capuchin Monkey", + Location = "Central & South America", + Details = "The capuchin monkeys are New World monkeys of the subfamily Cebinae. Prior to 2011, the subfamily contained only a single genus, Cebus.", + ImageUrl = "http://upload.wikimedia.org/wikipedia/commons/thumb/4/40/Capuchin_Costa_Rica.jpg/200px-Capuchin_Costa_Rica.jpg" + }); + + Monkeys.Add(new Issue7865Model + { + Index = 2, + Name = "Blue Monkey", + Location = "Central and East Africa", + Details = "The blue monkey or diademed monkey is a species of Old World monkey native to Central and East Africa, ranging from the upper Congo River basin east to the East African Rift and south to northern Angola and Zambia", + ImageUrl = "http://upload.wikimedia.org/wikipedia/commons/thumb/8/83/BlueMonkey.jpg/220px-BlueMonkey.jpg" + }); + + Monkeys.Add(new Issue7865Model + { + Index = 3, + Name = "Thomas's Langur", + Location = "Indonesia", + Details = "Thomas's langur is a species of primate in the family Cercopithecidae. It is endemic to North Sumatra, Indonesia. Its natural habitat is subtropical or tropical dry forests. It is threatened by habitat loss. Its native names are reungkah in Acehnese and kedih in Alas.", + ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/3/31/Thomas%27s_langur_Presbytis_thomasi.jpg/142px-Thomas%27s_langur_Presbytis_thomasi.jpg" + }); + + Monkeys.Add(new Issue7865Model + { + Index = 4, + Name = "Purple-faced Langur", + Location = "Sri Lanka", + Details = "The purple-faced langur, also known as the purple-faced leaf monkey, is a species of Old World monkey that is endemic to Sri Lanka. The animal is a long-tailed arboreal species, identified by a mostly brown appearance, dark face (with paler lower face) and a very shy nature. The species was once highly prevalent, found in suburban Colombo and the \"wet zone\" villages (areas with high temperatures and high humidity throughout the year, whilst rain deluges occur during the monsoon seasons), but rapid urbanization has led to a significant decrease in the population level of the monkeys.", + ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/Semnopithèque_blanchâtre_mâle.JPG/192px-Semnopithèque_blanchâtre_mâle.JPG" + }); + } + } +} \ No newline at end of file diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems index 8a33c64..a70ab04 100644 --- a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems @@ -75,6 +75,9 @@ Code + + Code + @@ -1455,6 +1458,9 @@ Issue7943.xaml + + Issue7865.xaml + @@ -1537,8 +1543,10 @@ Designer MSBuild:Compile - - + + Designer + MSBuild:Compile + Designer MSBuild:Compile diff --git a/Xamarin.Forms.Core/Items/CarouselView.cs b/Xamarin.Forms.Core/Items/CarouselView.cs index 9e09f9c..479b9df 100644 --- a/Xamarin.Forms.Core/Items/CarouselView.cs +++ b/Xamarin.Forms.Core/Items/CarouselView.cs @@ -165,6 +165,9 @@ namespace Xamarin.Forms set => SetValue(ItemsLayoutProperty, value); } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool IsScrolling { get; set; } + public event EventHandler CurrentItemChanged; public event EventHandler PositionChanged; @@ -214,8 +217,8 @@ namespace Xamarin.Forms carousel.PositionChanged?.Invoke(carousel, args); - //user is interacting with the carousel we don't need to scroll to item - if (!carousel.IsDragging) + // If the user is interacting with the Carousel or the Carousel is doing ScrollTo, we don't need to scroll to item. + if (!carousel.IsDragging && !carousel.IsScrolling) carousel.ScrollTo(args.CurrentPosition, position: ScrollToPosition.Center, animate: carousel.IsScrollAnimated); carousel.OnPositionChanged(args); diff --git a/Xamarin.Forms.Platform.Android/CollectionView/CarouselViewRenderer.cs b/Xamarin.Forms.Platform.Android/CollectionView/CarouselViewRenderer.cs index fcd581b..021cb07 100644 --- a/Xamarin.Forms.Platform.Android/CollectionView/CarouselViewRenderer.cs +++ b/Xamarin.Forms.Platform.Android/CollectionView/CarouselViewRenderer.cs @@ -86,6 +86,8 @@ namespace Xamarin.Forms.Platform.Android else Carousel.SetIsDragging(false); } + + Carousel.IsScrolling = state != ScrollStateIdle; } protected override ItemDecoration CreateSpacingDecoration(IItemsLayout itemsLayout) diff --git a/Xamarin.Forms.Platform.UAP/CollectionView/CarouselViewRenderer.cs b/Xamarin.Forms.Platform.UAP/CollectionView/CarouselViewRenderer.cs index f373961..d129b47 100644 --- a/Xamarin.Forms.Platform.UAP/CollectionView/CarouselViewRenderer.cs +++ b/Xamarin.Forms.Platform.UAP/CollectionView/CarouselViewRenderer.cs @@ -142,11 +142,13 @@ namespace Xamarin.Forms.Platform.UWP void OnScrollViewChanging(object sender, ScrollViewerViewChangingEventArgs e) { CarouselView.SetIsDragging(true); + CarouselView.IsScrolling = true; } void OnScrollViewChanged(object sender, ScrollViewerViewChangedEventArgs e) { CarouselView.SetIsDragging(e.IsIntermediate); + CarouselView.IsScrolling = e.IsIntermediate; } void UpdatePeekAreaInsets() diff --git a/Xamarin.Forms.Platform.iOS/CollectionView/CarouselViewController.cs b/Xamarin.Forms.Platform.iOS/CollectionView/CarouselViewController.cs index 936e02b..2d0e068 100644 --- a/Xamarin.Forms.Platform.iOS/CollectionView/CarouselViewController.cs +++ b/Xamarin.Forms.Platform.iOS/CollectionView/CarouselViewController.cs @@ -79,6 +79,11 @@ namespace Xamarin.Forms.Platform.iOS _carouselView.SetIsDragging(false); } + internal void UpdateIsScrolling(bool isScrolling) + { + _carouselView.IsScrolling = isScrolling; + } + void UpdateInitialPosition() { if (_carouselView.Position != 0) diff --git a/Xamarin.Forms.Platform.iOS/CollectionView/CarouselViewDelegator.cs b/Xamarin.Forms.Platform.iOS/CollectionView/CarouselViewDelegator.cs index 26144b0..368c0d8 100644 --- a/Xamarin.Forms.Platform.iOS/CollectionView/CarouselViewDelegator.cs +++ b/Xamarin.Forms.Platform.iOS/CollectionView/CarouselViewDelegator.cs @@ -9,6 +9,23 @@ namespace Xamarin.Forms.Platform.iOS { } + public override void Scrolled(UIScrollView scrollView) + { + base.Scrolled(scrollView); + + (ViewController as CarouselViewController)?.UpdateIsScrolling(true); + } + + public override void ScrollAnimationEnded(UIScrollView scrollView) + { + (ViewController as CarouselViewController)?.UpdateIsScrolling(false); + } + + public override void DecelerationEnded(UIScrollView scrollView) + { + (ViewController as CarouselViewController)?.UpdateIsScrolling(false); + } + public override void DraggingStarted(UIScrollView scrollView) { ViewController?.DraggingStarted(scrollView); -- 2.7.4