Xamarin Forms kneifen und in der Pfanne zusammen
Implementierte ich die beiden Schwenk-und pinch-individuell, und es funktioniert gut. Ich bin jetzt versucht, Quetsch-und pan zusammen und ich sehe einige Probleme. Hier ist mein code:
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>
Prise/Pan-Geste Add:
var panGesture = new PanGestureRecognizer();
panGesture.PanUpdated += OnPanUpdated;
GestureRecognizers.Add(panGesture);
var pinchGesture = new PinchGestureRecognizer();
pinchGesture.PinchUpdated += OnPinchUpdated;
GestureRecognizers.Add(pinchGesture);
Pan-Methode:
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;
}
}
Pinch-Methode:
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;
}
}
Wenn ich schalten Sie entweder die Geste und verwenden Sie nur das dann die anderen Funktionen funktioniert perfekt. Das Problem entsteht, wenn ich die Schwenk-UND pinch-gesten. Was passiert zu sein scheint, ist dies:
1) Die pan scheint tatsächlich so zu funktionieren, wie erwartet
2) Wenn Sie pan auf dem Bild zunächst, sagen wir, bewegen Sie das Bild in Y-Mitte und X-center, und dann versuchen Sie, um zu vergrößern, wird das Bild wieder zurück, um es in den ursprünglichen Zustand. Dann, wenn Sie pan, es führt Sie zurück zu, wo Sie waren, bevor Sie versucht, zu Zoomen (das ist, warum ich sagen, die Pfanne ist in Ordnung).
Von dem, was ich das Verständnis von meinem Debuggen ist, dass beim zoom ist es nicht unter Berücksichtigung der position, die Sie derzeit bei. Also, wenn Sie pan und zoom, ist es nicht zoom auf die position, die Sie sind, sondern der Anfangspunkt des Bildes. Dann, wenn Sie versuchen, Pfanne von dort, die pan-Methode erinnert sich noch daran, wo Sie waren, und es führt Sie zurück zu, wo Sie waren, bevor Sie versucht haben, um zu Zoomen.
Hoffen, einige Einblicke in das. Offensichtlich gibt es ein Problem mit meiner pinch-Methode. Ich denke nur (offensichtlich nicht herausfinden können) ich muss hinzufügen von Logik in es berücksichtigt werden sollten, wo Sie derzeit bei.
- Hast du am Ende immer das funktioniert?
- Ja, habe ich, endete, etwas anderes zu tun als dieses, um es zu arbeiten. Ich werde meine Methoden unten.
- Ich danke Ihnen so sehr. Ich werde das ausprobieren.
- upvote, wenn es für Sie funktioniert 🙂 auch gerne helfen, wenn Sie Probleme haben.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den wichtigsten Grund könnte sein, dass jeder scheint zu kopieren und verwenden Sie diesen code (kommt aus dem dev.xamarin Website) mit seinen sehr verworrenen und sehr unnötige co-ordinate Berechnungen :-). Unnötig, da konnten wir einfach bitten, die Ansicht zu tun, die schweres heben für uns, mit der
AnchorX
undAnchorY
Eigenschaften, die dienen genau diesem Zweck.Wir haben ein Doppel-tap Betrieb zu vergrößern und wiederherstellen der ursprünglichen Skala. Beachten Sie, dass, weil Xamarin nicht um Werte in einem Koordinatensystem mit seinen
Tap
Veranstaltungen (eine sehr unkluge Entscheidung, tatsächlich), können wir nur den zoom von der Mitte jetzt:Die pinch-handler ist ähnlich einfach, keine Notwendigkeit zu berechnen, auch alle übersetzungen bei allen. Alles, was wir tun müssen, ist, um die Anker der Prise Ausgangspunkt und Rahmen werden den rest tun, die Skalierung auftreten, um diesen Punkt. Beachten Sie, dass wir haben sogar eine extra Funktion hier, federnden absprung-zurück auf überschwingen an beiden enden der zoom-Skala.
Und der panning-handler, noch einfacher. Auf der Startseite, berechnen wir den Ausgangspunkt, von dem Anker, und während Kameraschwenks, halten wir die änderung der Anker. Dieser Anker wird relativ zum Ansichtsbereich, können wir leicht Klemmen Sie es zwischen 0 und 1, und dies beendet das panning bei den extremen ohne jegliche übersetzung Berechnung überhaupt.
Konstanten und Variablen verwendet werden, sind nur diese:
Anchor
Werte sind normalisiert auf die 0..1-Bereich, brauchen Sie nicht mehr als das.ZoomImage
ausImage
ergänzt der Handler und wo immer ich es benutzt habe, gab es pinch and pan und alles.Scale
etc direkt.Ging mit einer völlig anderen Methode, der Umgang mit dieser. Für jeden, der Probleme hat, diese funktioniert zu 100%.
OnPanUpdated
OnPinchUpdated
OnSizeAllocated (die meisten von diesen werden Sie wahrscheinlich nicht brauchen, aber einige, die Sie tun. betrachten
ScreenWidth
,ScreenHeight
,yOffset
,xOffset
,currentScale
)Layout (XAML, C#)
Bei mir funktionierte es wie folgt, habe gerade einige änderungen in den code in die Frage,
Pan-Code