Teilen über


Hinzufügen einer Zusammendrückgestenerkennung

Die Zusammendrückbewegung wird zum Ausführen des interaktiven Zooms verwendet und mit der Klasse „PinchGestureRecognizer“ implementiert. Allgemein wird die Zusammendrückbewegung verwendet, um einen interaktiven Zoom eines Bildes im Speicherort der Zusammendrückbewegung auszuführen. Dies wird durch Skalierung des Anzeigebereichs erreicht und in diesem Artikel veranschaulicht.

Erstellen Sie eine Instanz PinchGestureRecognizer, bearbeiten Sie das Ereignis PinchUpdated, und fügen Sie die neue Funktion zur Gestenerkennung der Sammlung GestureRecognizers im Benutzeroberflächenelement hinzu, damit ein Benutzeroberflächenelement mit der Zusammendrückbewegung vergrößert werden kann. Das folgende Codebeispiel zeigt die Instanz PinchGestureRecognizer, die an das Element Image angefügt ist:

var pinchGesture = new PinchGestureRecognizer();
pinchGesture.PinchUpdated += (s, e) => {
  // Handle the pinch
};
image.GestureRecognizers.Add(pinchGesture);

Dies kann auch wie im folgenden Codebeispiel dargestellt in XAML erreicht werden:

<Image Source="waterfront.jpg">
  <Image.GestureRecognizers>
    <PinchGestureRecognizer PinchUpdated="OnPinchUpdated" />
  </Image.GestureRecognizers>
</Image>

Der Code für den Ereignishandler OnPinchUpdated wird dann zur CodeBehind-Datei hinzugefügt:

void OnPinchUpdated (object sender, PinchGestureUpdatedEventArgs e)
{
  // Handle the pinch
}

Erstellen des Containers „PinchToZoom“

Für das Verarbeiten der Zusammendrückbewegung zum Ausführen eines Zooms sind Berechnungen erforderlich, um die Benutzeroberfläche zu transformieren. Dieser Abschnitt enthält eine Hilfsprogrammklasse zum Ausführen der Berechnungen, damit jedes Benutzeroberflächenelement interaktiv vergrößert werden kann. Das folgende Codebeispiel zeigt die PinchToZoomContainer-Klasse:

public class PinchToZoomContainer : ContentView
{
  ...

  public PinchToZoomContainer ()
  {
    var pinchGesture = new PinchGestureRecognizer ();
    pinchGesture.PinchUpdated += OnPinchUpdated;
    GestureRecognizers.Add (pinchGesture);
  }

  void OnPinchUpdated (object sender, PinchGestureUpdatedEventArgs e)
  {
    ...
  }
}

Diese Klasse kann das Benutzeroberflächenelement umschließen, sodass die Zusammendrückbewegung das umschlossene Benutzeroberflächenelement vergrößert. Das folgende XAML-Codebeispiel stellt die Klasse PinchToZoomContainer dar, die ein Image-Element umschließt:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:PinchGesture;assembly=PinchGesture"
             x:Class="PinchGesture.HomePage">
    <ContentPage.Content>
        <Grid Padding="20">
            <local:PinchToZoomContainer>
                <local:PinchToZoomContainer.Content>
                    <Image Source="waterfront.jpg" />
                </local:PinchToZoomContainer.Content>
            </local:PinchToZoomContainer>
        </Grid>
    </ContentPage.Content>
</ContentPage>

Das folgende Codebeispiel veranschaulicht, wie die Klasse PinchToZoomContainer ein Image-Element auf einer C#-Seite umschließt:

public class HomePageCS : ContentPage
{
  public HomePageCS ()
  {
    Content = new Grid {
      Padding = new Thickness (20),
      Children = {
        new PinchToZoomContainer {
          Content = new Image { Source = ImageSource.FromFile ("waterfront.jpg") }
        }
      }
    };
  }
}

Wenn das Image Element eine Zusammendrückbewegung empfängt, wird das angezeigte Bild vergrößert oder verkleinert. Der Zoom wird von der PinchZoomContainer.OnPinchUpdated Methode ausgeführt, die im folgenden Codebeispiel dargestellt wird:

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;
    Content.AnchorX = 0;
    Content.AnchorY = 0;
  }
  if (e.Status == GestureStatus.Running) {
    // Calculate the scale factor to be applied.
    currentScale += (e.Scale - 1) * startScale;
    currentScale = Math.Max (1, currentScale);

    // 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;
  }
}

Diese Methode aktualisiert die Zoomstufe des umschlossenen Benutzeroberflächenelements basierend auf der Zusammendrückbewegung des Benutzers. Durch die Verwendung der Werte der Eigenschaften Scale, ScaleOrigin und Status der Instanz PinchGestureUpdatedEventArgs wird der Skalierungsfaktor berechnet, der am Anfang der Zusammendrückbewegung angewendet werden soll. Das umschlossene Benutzeroberflächenelement wird anschließend am Anfang der Zusammendrückbewegung vergrößert, indem die Eigenschaften TranslationX, TranslationY und Scale auf die berechneten Werte eingestellt werden.