Aracılığıyla paylaş


Sıkıştırma hareketi tanıyıcısı ekleme

Sıkıştırma hareketi etkileşimli yakınlaştırma gerçekleştirmek için kullanılır ve PinchGestureRecognizer sınıfıyla uygulanır. Sıkıştırma hareketinin yaygın senaryolarından biri, sıkıştırma konumundaki bir görüntünün etkileşimli yakınlaştırmasını gerçekleştirmektir. Bu, görünüm penceresi içeriğini ölçeklendirerek gerçekleştirilir ve bu makalede gösterilmiştir.

Bir kullanıcı arabirimi öğesini sıkıştırma hareketiyle yakınlaştırılabilir hale getirmek için bir PinchGestureRecognizer örnek oluşturun, olayı işleyin PinchUpdated ve kullanıcı arabirimi öğesindeki koleksiyona GestureRecognizers yeni hareket tanıyıcısını ekleyin. Aşağıdaki kod örneği, bir öğeye eklenmiş bir PinchGestureRecognizerImage öğeyi gösterir:

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

Bu, aşağıdaki kod örneğinde gösterildiği gibi XAML'de de elde edilebilir:

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

Ardından olay işleyicisinin OnPinchUpdated kodu arka planda kod dosyasına eklenir:

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

PinchToZoom kapsayıcısı oluşturma

Yakınlaştırma işlemi gerçekleştirmek için sıkıştırma hareketini işlemek için kullanıcı arabirimini dönüştürmek için biraz matematik gerekir. Bu bölüm, herhangi bir kullanıcı arabirimi öğesini etkileşimli olarak yakınlaştırmak için kullanılabilen matematik işlemlerini gerçekleştirmek için genelleştirilmiş bir yardımcı sınıfı içerir. Aşağıdaki kod örneği sınıfını PinchToZoomContainer gösterir:

public class PinchToZoomContainer : ContentView
{
  ...

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

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

Bu sınıf, sarmalanmış kullanıcı arabirimi öğesini yakınlaştırmak için bir kullanıcı arabirimi öğesi çevresinde sarmalanabilir. Aşağıdaki XAML kodu örneği, bir Image öğenin sarmalama işlemini PinchToZoomContainer gösterir:

<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>

Aşağıdaki kod örneği, bir Image öğenin C# sayfasında nasıl kaydırılır PinchToZoomContainer gösterir:

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

Image Öğe bir sıkıştırma hareketi aldığında, görüntülenen görüntü yakınlaştırılır veya uzaklaştırılır. Yakınlaştırma, aşağıdaki kod örneğinde gösterilen yöntemiyle PinchZoomContainer.OnPinchUpdated gerçekleştirilir:

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

Bu yöntem, sarmalanan kullanıcı arabirimi öğesinin yakınlaştırma düzeyini kullanıcının sıkıştırma hareketlerine göre güncelleştirir. Bu, sıkıştırma hareketinin ScaleScaleOrigin kaynağında uygulanacak ölçek faktörünü hesaplamak için örneğin değerleri ve Status özellikleri PinchGestureUpdatedEventArgs kullanılarak elde edilir. Sarmalanan kullanıcı öğesi daha sonra, , TranslationYve Scale özelliklerini hesaplanan değerlere ayarlayarak TranslationXsıkıştırma hareketinin başlangıcına yakınlaştırılır.