Xamarin Формы сжимают и панорамируют вместе
Я реализовал панорамирование и пинчирование по отдельности, и все работает отлично. Я сейчас пытаюсь использовать пинч и панорамирование вместе, и я вижу некоторые проблемы. Вот мой код:
XAML:
<AbsoluteLayout x:Name="PinchZoomContainer">
<controls:NavBar x:Name="NavBar" ShowPrevNext="true" ShowMenu="false" IsModal="true" />
<controls:PanContainer x:Name="PinchToZoomContainer">
<Image x:Name="ImageMain" />
</controls:PanContainer>
</AbsoluteLayout>
Щепотка / Пан Жест Добавляет:
var panGesture = new PanGestureRecognizer();
panGesture.PanUpdated += OnPanUpdated;
GestureRecognizers.Add(panGesture);
var pinchGesture = new PinchGestureRecognizer();
pinchGesture.PinchUpdated += OnPinchUpdated;
GestureRecognizers.Add(pinchGesture);
Пан метод:
void OnPanUpdated(object sender, PanUpdatedEventArgs e)
{
switch (e.StatusType)
{
case GestureStatus.Started:
startX = e.TotalX;
startY = e.TotalY;
Content.AnchorX = 0;
Content.AnchorY = 0;
break;
case GestureStatus.Running:
// Translate and ensure we don't pan beyond the wrapped user interface element bounds.
Content.TranslationX = Math.Max(Math.Min(0, x + e.TotalX), -Math.Abs(Content.Width - App.ScreenWidth));
Content.TranslationY = Math.Max(Math.Min(0, y + e.TotalY), -Math.Abs(Content.Height - App.ScreenHeight));
break;
case GestureStatus.Completed:
// Store the translation applied during the pan
x = Content.TranslationX;
y = Content.TranslationY;
break;
}
}
Метод щепотки:
void OnPinchUpdated(object sender, PinchGestureUpdatedEventArgs e)
{
if (e.Status == GestureStatus.Started)
{
// Store the current scale factor applied to the wrapped user interface element,
// and zero the components for the center point of the translate transform.
startScale = Content.Scale;
//ImageMain.AnchorX = 0;
//ImageMain.AnchorY = 0;
}
if (e.Status == GestureStatus.Running)
{
// Calculate the scale factor to be applied.
currentScale += (e.Scale - 1) * startScale;
currentScale = Math.Max(1, currentScale);
currentScale = Math.Min(currentScale, 2.5);
// The ScaleOrigin is in relative coordinates to the wrapped user interface element,
// so get the X pixel coordinate.
double renderedX = Content.X + xOffset;
double deltaX = renderedX / Width;
double deltaWidth = Width / (Content.Width * startScale);
double originX = (e.ScaleOrigin.X - deltaX) * deltaWidth;
// The ScaleOrigin is in relative coordinates to the wrapped user interface element,
// so get the Y pixel coordinate.
double renderedY = Content.Y + yOffset;
double deltaY = renderedY / Height;
double deltaHeight = Height / (Content.Height * startScale);
double originY = (e.ScaleOrigin.Y - deltaY) * deltaHeight;
// Calculate the transformed element pixel coordinates.
double targetX = xOffset - (originX * Content.Width) * (currentScale - startScale);
double targetY = yOffset - (originY * Content.Height) * (currentScale - startScale);
// Apply translation based on the change in origin.
Content.TranslationX = targetX.Clamp(-Content.Width * (currentScale - 1), 0);
Content.TranslationY = targetY.Clamp(-Content.Height * (currentScale - 1), 0);
// Apply scale factor
Content.Scale = currentScale;
}
if (e.Status == GestureStatus.Completed)
{
// Store the translation delta's of the wrapped user interface element.
xOffset = Content.TranslationX;
yOffset = Content.TranslationY;
}
}
Если я отключаю один жест и использую только другой, то функциональность работает отлично. Проблема возникает, когда я добавляю жесты сдвига и сдвига. Кажется, что происходит, это:
1) Кажется, что панорамирование работает, как и ожидалось. 2) При первоначальном панорамировании изображения, скажем, перемещаем изображение в Y-центр и X-центр, а затем вы пытаетесь увеличить изображение, изображение возвращается к начальное состояние. Затем, когда вы перемещаетесь, он возвращает вас туда, где вы были до того, как пытались увеличить изображение (именно поэтому я говорю, что панорамирование работает нормально).
Из моей отладки я понимаю, что при масштабировании не учитывается положение, в котором вы сейчас находитесь. Поэтому, когда вы сначала перемещаетесь, а затем увеличиваете масштаб, он не увеличивает положение, в котором вы находитесь, а в начальной точке изображения. Затем, когда вы пытаетесь выполнить панорамирование оттуда, метод панорамирования все еще запоминает, где вы были, и возвращает вас туда, где вы были до того, как пытались увеличить масштаб.
Надеюсь немного понять это. Очевидно, есть проблема с моим методом щепотки. Я просто думаю (очевидно, не могу понять), мне нужно добавить логику, которая учитывает, где вы находитесь в данный момент.