I'm trying to make a layout that allow me to move controls inside it freely, I found a working solution but it has a very strange behavior, when I try to move the label, the movement is very laggy and sometimis it has an effect like it duplicate the label.
I implemented the movement with a PanGestureRecognizer adding labels inside an AbsoluteLayout programatically with a button event
This is the XAML, with the empty AbsoluteLayout and the button at the end to add de label
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Views.MoveControlsView"
Title="MoveControlsView">
<StackLayout>
<AbsoluteLayout
x:Name="ParentLayout"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand">
</AbsoluteLayout>
<StackLayout
HorizontalOptions="FillAndExpand"
VerticalOptions="End">
<Button
x:Name="AddLabel"
Text="Add label"
Clicked="AddLabel_Clicked"/>
</StackLayout>
</StackLayout>
</ContentPage>
This is the code behind, I generate a Label when the button is clicked and add to it the PanGestureRecognizer that I also suscribed it to the PanUpdated event.
public partial class MoveControlsView : ContentPage
{
public MoveControlsView()
{
InitializeComponent();
}
private void AddLabel_Clicked(object sender, EventArgs e)
{
var label = new Label()
{
Text = "This is a label",
BackgroundColor = Colors.LightGray,
Padding = 10
};
var panGesture = new PanGestureRecognizer();
panGesture.PanUpdated += PanGestureRecognizer_PanUpdated;
label.GestureRecognizers.Add(panGesture);
ParentLayout.Children.Add(label);
}
private void PanGestureRecognizer_PanUpdated(object sender, PanUpdatedEventArgs e)
{
var label = sender as Label;
switch (e.StatusType)
{
case GestureStatus.Running:
label.TranslationX = e.TotalX;
label.TranslationY = e.TotalY;
break;
case GestureStatus.Completed:
label.TranslateTo(label.TranslationX, label.TranslationY);
break;
}
}
}
You could make changes to the code in PanGestureRecognizer_PanUpdated event handler. Try the following code:
double tempx = 0;
double tempy = 0;
private void PanGestureRecognizer_PanUpdated(object sender, PanUpdatedEventArgs e)
{
var label = sender as Label;
switch (e.StatusType)
{
case GestureStatus.Started:
if(Device.RuntimePlatform == Device.iOS)
{
tempx = label.TranslationX;
tempy = label.TranslationY;
}
break;
case GestureStatus.Running:
if (Device.RuntimePlatform == Device.iOS)
{
label.TranslationX = e.TotalX + tempx;
label.TranslationY = e.TotalY + tempy;
}
else if (Device.RuntimePlatform == Device.Android)
{
label.TranslationX += e.TotalX;
label.TranslationY += e.TotalY;
}
break;
case GestureStatus.Completed:
tempx = label.TranslationX;
tempy = label.TranslationY;
break;
}
}
For more information, you could refer to Xamarin.Forms AbsoluteLayout and Add a pan gesture recognizer
Hope it works for you.