From 85a3e74d17af08806bd989280c57ba5a24424176 Mon Sep 17 00:00:00 2001 From: vryan95 Date: Sat, 2 Nov 2024 00:54:58 +0100 Subject: [PATCH 1/3] Update packages, reorganize SwipeCardView, and refactor code Updated `Microsoft.Maui.Controls` to version `8.0.92` and `Microsoft.Extensions.Logging.Debug` to version `8.0.1` in project files. Added `Microsoft.Maui.Controls.Compatibility` package reference. Reorganized `SwipeCardView.cs` with regions for better code structure. Moved `OnPanUpdated` to `Event Handlers` region and added a new method for pan gesture updates. Removed `DraggingCardPosition` property, initializing it in the constructor. Moved `SwipeCardDirectionExtensions` to a separate file and cleaned up redundant code and `using` directives. --- .../SwipeCardView.Sample.csproj | 8 +- .../Plugin.Maui.SwipeCardView.csproj | 8 +- .../SwipeCardDirectionExtensions.cs | 31 ++++ .../SwipeCardView.cs | 144 ++++++++---------- 4 files changed, 105 insertions(+), 86 deletions(-) create mode 100644 src/Plugin.Maui.SwipeCardView/SwipeCardDirectionExtensions.cs diff --git a/samples/SwipeCardView.Sample/SwipeCardView.Sample.csproj b/samples/SwipeCardView.Sample/SwipeCardView.Sample.csproj index 906ff85..c98e26c 100644 --- a/samples/SwipeCardView.Sample/SwipeCardView.Sample.csproj +++ b/samples/SwipeCardView.Sample/SwipeCardView.Sample.csproj @@ -57,12 +57,16 @@ - - + + + + + + diff --git a/src/Plugin.Maui.SwipeCardView/Plugin.Maui.SwipeCardView.csproj b/src/Plugin.Maui.SwipeCardView/Plugin.Maui.SwipeCardView.csproj index 0388492..c7b269c 100644 --- a/src/Plugin.Maui.SwipeCardView/Plugin.Maui.SwipeCardView.csproj +++ b/src/Plugin.Maui.SwipeCardView/Plugin.Maui.SwipeCardView.csproj @@ -37,14 +37,16 @@ - - + - + + + + \ No newline at end of file diff --git a/src/Plugin.Maui.SwipeCardView/SwipeCardDirectionExtensions.cs b/src/Plugin.Maui.SwipeCardView/SwipeCardDirectionExtensions.cs new file mode 100644 index 0000000..4fa4524 --- /dev/null +++ b/src/Plugin.Maui.SwipeCardView/SwipeCardDirectionExtensions.cs @@ -0,0 +1,31 @@ +using Plugin.Maui.SwipeCardView.Core; + +namespace Plugin.Maui.SwipeCardView; + +internal static class SwipeCardDirectionExtensions +{ + public static bool IsLeft(this SwipeCardDirection self) + { + return (self & SwipeCardDirection.Left) == SwipeCardDirection.Left; + } + + public static bool IsRight(this SwipeCardDirection self) + { + return (self & SwipeCardDirection.Right) == SwipeCardDirection.Right; + } + + public static bool IsUp(this SwipeCardDirection self) + { + return (self & SwipeCardDirection.Up) == SwipeCardDirection.Up; + } + + public static bool IsDown(this SwipeCardDirection self) + { + return (self & SwipeCardDirection.Down) == SwipeCardDirection.Down; + } + + public static bool IsSupported(this SwipeCardDirection self, SwipeCardDirection other) + { + return (self & other) == other; + } +} \ No newline at end of file diff --git a/src/Plugin.Maui.SwipeCardView/SwipeCardView.cs b/src/Plugin.Maui.SwipeCardView/SwipeCardView.cs index 6720b6a..d49b6db 100644 --- a/src/Plugin.Maui.SwipeCardView/SwipeCardView.cs +++ b/src/Plugin.Maui.SwipeCardView/SwipeCardView.cs @@ -1,18 +1,15 @@ -using Plugin.Maui.SwipeCardView.Core; -using System; +using Microsoft.Maui.Controls.Compatibility; +using Plugin.Maui.SwipeCardView.Core; using System.Collections; using System.Collections.Specialized; using System.Diagnostics; -using System.Threading.Tasks; using System.Windows.Input; -using Microsoft.Maui.Controls; -using Microsoft.Maui.Controls.Compatibility; -using Microsoft.Maui; namespace Plugin.Maui.SwipeCardView; public class SwipeCardView : ContentView, IDisposable { + #region Bindable Properties public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create( nameof(ItemsSource), @@ -118,6 +115,9 @@ public class SwipeCardView : ContentView, IDisposable typeof(SwipeCardView), DefaultLoopCards); + #endregion + + #region Constants private const uint DefaultThreshold = 100; private const SwipeCardDirection DefaultSupportedSwipeDirections = SwipeCardDirection.Left | SwipeCardDirection.Right | SwipeCardDirection.Up | SwipeCardDirection.Down; @@ -138,6 +138,9 @@ public class SwipeCardView : ContentView, IDisposable private const uint InvokeSwipeDefaultTouchDifference = 10; private const uint InvokeSwipeDefaultTouchDelay = 1; private const uint InvokeSwipeDefaultEndDelay = 200; + #endregion + + #region Private fields private readonly View[] _cards = new View[NumCards]; @@ -150,6 +153,7 @@ public class SwipeCardView : ContentView, IDisposable private int _itemIndex = 0; // The last items index added to the stack of the cards private bool _ignoreTouch = false; + #endregion public SwipeCardView() { @@ -160,30 +164,9 @@ public SwipeCardView() var panGesture = new PanGestureRecognizer(); panGesture.PanUpdated += OnPanUpdated; GestureRecognizers.Add(panGesture); - - DraggingCardPosition = DraggingCardPosition.Start; - } - - public void Dispose() - { - foreach (var card in _cards) - { - if (card != null) - Microsoft.Maui.Controls.ViewExtensions.CancelAnimations(card); - } - - GestureRecognizers.Clear(); - - if (this.ItemsSource != null) - { - var observable = this.ItemsSource as INotifyCollectionChanged; - if (observable != null) - { - observable.CollectionChanged -= this.OnItemSourceCollectionChanged; - } - } } + #region Public Properties public event EventHandler Swiped; public event EventHandler Dragging; @@ -279,7 +262,28 @@ public bool LoopCards set => SetValue(LoopCardsProperty, value); } - private DraggingCardPosition DraggingCardPosition { get; set; } + #endregion + + #region Public Methods + public void Dispose() + { + foreach (var card in _cards) + { + if (card != null) + Microsoft.Maui.Controls.ViewExtensions.CancelAnimations(card); + } + + GestureRecognizers.Clear(); + + if (ItemsSource != null) + { + var observable = ItemsSource as INotifyCollectionChanged; + if (observable != null) + { + observable.CollectionChanged -= OnItemSourceCollectionChanged; + } + } + } /// /// Simulates PanGesture movement to left or right @@ -344,7 +348,9 @@ public async Task InvokeSwipe(SwipeCardDirection swipeCardDirection, uint number HandleTouchEnd(); } + #endregion + #region Event Handlers private static void OnItemTemplatePropertyChanged(BindableObject bindable, object oldValue, object newValue) { var swipeCardView = (SwipeCardView)bindable; @@ -426,6 +432,32 @@ private void OnItemSourceCollectionChanged(object sender, NotifyCollectionChange } } + private void OnPanUpdated(object sender, PanUpdatedEventArgs e) + { + if (ItemsSource == null || ItemsSource.Count == 0) + { + return; + } + + switch (e.StatusType) + { + case GestureStatus.Started: + HandleTouchStart(); + break; + + case GestureStatus.Running: + HandleTouch((float)e.TotalX, (float)e.TotalY); + break; + + case GestureStatus.Completed: + HandleTouchEnd(); + break; + } + } + + #endregion + + #region Private Methods private void Setup() { if (ItemsSource == null) @@ -468,30 +500,7 @@ private void Setup() } Content.IsVisible = wasVisible; } - - private void OnPanUpdated(object sender, PanUpdatedEventArgs e) - { - if (ItemsSource == null || ItemsSource.Count == 0) - { - return; - } - - switch (e.StatusType) - { - case GestureStatus.Started: - HandleTouchStart(); - break; - - case GestureStatus.Running: - HandleTouch((float)e.TotalX, (float)e.TotalY); - break; - - case GestureStatus.Completed: - HandleTouchEnd(); - break; - } - } - + // Handle when a touch event begins private void HandleTouchStart() { @@ -721,32 +730,5 @@ private void SendDragging(View sender, SwipeCardDirection direction, DraggingCar Dragging?.Invoke(sender, new DraggingCardEventArgs(sender.BindingContext, DraggingCommandParameter, direction, position, distanceDraggedX, distanceDraggedY)); } -} - -internal static class SwipeCardDirectionExtensions -{ - public static bool IsLeft(this SwipeCardDirection self) - { - return (self & SwipeCardDirection.Left) == SwipeCardDirection.Left; - } - - public static bool IsRight(this SwipeCardDirection self) - { - return (self & SwipeCardDirection.Right) == SwipeCardDirection.Right; - } - - public static bool IsUp(this SwipeCardDirection self) - { - return (self & SwipeCardDirection.Up) == SwipeCardDirection.Up; - } - - public static bool IsDown(this SwipeCardDirection self) - { - return (self & SwipeCardDirection.Down) == SwipeCardDirection.Down; - } - - public static bool IsSupported(this SwipeCardDirection self, SwipeCardDirection other) - { - return (self & other) == other; - } + #endregion } \ No newline at end of file From 62c2dce1c7f3ec816170a37c606c7c0f4fe9ebad Mon Sep 17 00:00:00 2001 From: vryan95 Date: Sat, 2 Nov 2024 02:21:59 +0100 Subject: [PATCH 2/3] Refactor SwipeCardView to use Grid layout Removed UseSwipeCardView extension method from MauiProgram.cs. Deleted AppBuilderExtensions.cs, which contained the extension method. Updated SwipeCardView to use Grid instead of RelativeLayout. Removed Microsoft.Maui.Controls.Compatibility namespace import. Revised card stacking logic to iterate in reverse order. Changed card addition to use Grid.Children.Add. Implemented z-index management using Grid's ZIndex property. Adjusted swipe handling to modify ZIndex of the top card. --- samples/SwipeCardView.Sample/MauiProgram.cs | 1 - .../AppBuilderExtensions.cs | 21 ------------------ .../SwipeCardView.cs | 22 ++++++++----------- 3 files changed, 9 insertions(+), 35 deletions(-) delete mode 100644 src/Plugin.Maui.SwipeCardView/AppBuilderExtensions.cs diff --git a/samples/SwipeCardView.Sample/MauiProgram.cs b/samples/SwipeCardView.Sample/MauiProgram.cs index d406bb3..89b07ff 100644 --- a/samples/SwipeCardView.Sample/MauiProgram.cs +++ b/samples/SwipeCardView.Sample/MauiProgram.cs @@ -10,7 +10,6 @@ public static MauiApp CreateMauiApp() var builder = MauiApp.CreateBuilder(); builder .UseMauiApp() - .UseSwipeCardView() .ConfigureFonts(fonts => { fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); diff --git a/src/Plugin.Maui.SwipeCardView/AppBuilderExtensions.cs b/src/Plugin.Maui.SwipeCardView/AppBuilderExtensions.cs deleted file mode 100644 index 121858e..0000000 --- a/src/Plugin.Maui.SwipeCardView/AppBuilderExtensions.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Microsoft.Maui.Hosting; -using Microsoft.Maui.Controls.Compatibility.Hosting; - -namespace Plugin.Maui.SwipeCardView; - -/// -/// Extensions for MauiAppBuilder -/// -public static class AppBuilderExtensions -{ - /// - /// Initializes the Plugin.Maui.SwipeCardView library. - /// - /// generated by . - /// initialized for . - public static MauiAppBuilder UseSwipeCardView(this MauiAppBuilder builder) - { - builder.UseMauiCompatibility(); - return builder; - } -} \ No newline at end of file diff --git a/src/Plugin.Maui.SwipeCardView/SwipeCardView.cs b/src/Plugin.Maui.SwipeCardView/SwipeCardView.cs index d49b6db..5113299 100644 --- a/src/Plugin.Maui.SwipeCardView/SwipeCardView.cs +++ b/src/Plugin.Maui.SwipeCardView/SwipeCardView.cs @@ -1,5 +1,4 @@ -using Microsoft.Maui.Controls.Compatibility; -using Plugin.Maui.SwipeCardView.Core; +using Plugin.Maui.SwipeCardView.Core; using System.Collections; using System.Collections.Specialized; using System.Diagnostics; @@ -157,7 +156,7 @@ public class SwipeCardView : ContentView, IDisposable public SwipeCardView() { - var view = new RelativeLayout(); + var view = new Grid(); Content = view; @@ -362,10 +361,10 @@ private static void OnItemTemplatePropertyChanged(BindableObject bindable, objec swipeCardView.Content = null; - var view = new RelativeLayout(); + var view = new Grid(); // create a stack of cards - for (var i = 0; i < NumCards; i++) + for (var i = NumCards-1; i >= 0; i--) { var content = swipeCardView.ItemTemplate.CreateContent(); if (!(content is View) && !(content is ViewCell)) @@ -379,12 +378,7 @@ private static void OnItemTemplatePropertyChanged(BindableObject bindable, objec card.IsVisible = false; Microsoft.Maui.Controls.ViewExtensions.CancelAnimations(card); - view.Children.Add( - card, - Constraint.Constant(0), - Constraint.Constant(0), - Constraint.RelativeToParent(parent => parent.Width), - Constraint.RelativeToParent(parent => parent.Height)); + view.Children.Add(card); } swipeCardView.Content = view; @@ -494,7 +488,8 @@ private void Setup() card.Rotation = 0; card.TranslationX = 0; card.TranslationY = -card.Y; - ((RelativeLayout)Content).LowerChild(card); + var minZIndex = ((Grid)Content).Children.Select(x => x.ZIndex).Min(); + card.ZIndex = minZIndex - 1; card.IsVisible = true; _itemIndex++; } @@ -665,7 +660,8 @@ private void ShowNextCard() if (_itemIndex < ItemsSource.Count) { // Push it to the back z order - ((RelativeLayout)Content).LowerChild(topCard); + var minZIndex = ((Grid)Content).Children.Select(x => x.ZIndex).Min(); + topCard.ZIndex = minZIndex -1; try { From bb5a998a28501d4d587653ddf66431b2073d793d Mon Sep 17 00:00:00 2001 From: vryan95 Date: Mon, 4 Nov 2024 20:13:20 +0100 Subject: [PATCH 3/3] Fix issue with swipecontrols not working on android because of usage of Frame --- .../Views/ColorsPage.xaml | 2 +- .../Views/CustomizablePage.xaml | 2 +- .../Views/TinderPage.xaml | 2 +- .../SwipeCardView.cs | 33 ++++++++++++------- 4 files changed, 24 insertions(+), 15 deletions(-) diff --git a/samples/SwipeCardView.Sample/Views/ColorsPage.xaml b/samples/SwipeCardView.Sample/Views/ColorsPage.xaml index b6e49d4..3938729 100644 --- a/samples/SwipeCardView.Sample/Views/ColorsPage.xaml +++ b/samples/SwipeCardView.Sample/Views/ColorsPage.xaml @@ -18,7 +18,7 @@ Threshold="100"> - +