2016-07-29 3 views
1

У меня есть ярлык с большим количеством текста, который я хочу включить в распознавания распознавания жёсткого изображения и панорамирования. Я использовал рецепты здесь, а затем вложил их в каждый Другие.Xamarin Pinch для увеличения и панорамирования контейнеров, оставляющих свои границы

https://developer.xamarin.com/guides/xamarin-forms/user-interface/gestures/pinch/

https://developer.xamarin.com/guides/xamarin-forms/user-interface/gestures/pan/

Проблема заключается в том, как объекты-контейнеры позволяют перемещать метку полностью вне его нормальные границы в любом месте в пределах верхнего просмотра страницы уровня (как это показано на рисунках ниже).

Любые мысли о том, как реализовать некоторые ограничения на них? Я уверен, что это просто помещает некоторые ограничения на математику в код контейнера, но я еще не нашел правильного изменения.

Как вы можете видеть на этих изображениях, как контейнер с пинчем в объектив (без панорамирования), так и контейнер панорамирования (без масштабирования) позволяют вам изменять элемент управления, поэтому он выходит за пределы его границ.

Initial Layout:

Initial layout

Pinch-To-Zoom только

Pinch-To-Zoom only

панорамирование только

Panning Only

Pinch и P Н.

Pinch and Pan

Ссылки выше имеют код контейнера, но здесь это:

PinchToZoomContainer.cs

public class PinchToZoomContainer : ContentView 
{ 
    // Pinch Gesture variables 
    double currentScale = 1; 
    double startScale = 1; 
    double xOffset = 0; 
    double yOffset = 0; 


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

    } 



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

PanContainer.cs

public class PanContainer : ContentView 
{ 
    double startX, startY; 
    double x, y; 

    public PanContainer() 
    { 
     // Set PanGestureRecognizer.TouchPoints to control the 
     // number of touch points needed to pan 
     var panGesture = new PanGestureRecognizer(); 
     panGesture.PanUpdated += OnPanUpdated; 
     GestureRecognizers.Add (panGesture); 
    } 

    void OnPanUpdated (object sender, PanUpdatedEventArgs e) 
    { 
     switch (e.StatusType) { 

     case GestureStatus.Started: 
      startX = Content.TranslationX; 
      startY = Content.TranslationY; 
      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));// App.ScreenWidth)); 
      //Content.TranslationY = Math.Max (Math.Min (0, y + e.TotalY), -Math.Abs (Content.Height - App.ScreenHeight)); //App.ScreenHeight));  
      Content.TranslationX = startX + e.TotalX; 
      Content.TranslationY = startY + e.TotalY; 

      break; 

     case GestureStatus.Completed: 
      // Store the translation applied during the pan 
      x = Content.TranslationX; 
      y = Content.TranslationY; 
      break; 
     } 
    } 
} 

Я представляю себе, на PanContainer, моя проблема в этих строках, что я должен был прокомментировать o у:

  //Content.TranslationX = Math.Max (Math.Min (0, x + e.TotalX), -Math.Abs (Content.Width - App.ScreenWidth));// App.ScreenWidth)); 
      //Content.TranslationY = Math.Max (Math.Min (0, y + e.TotalY), -Math.Abs (Content.Height - App.ScreenHeight)); //App.ScreenHeight));  

Я изменил их к более простой версии, потому что я не могу найти App.ScreenWidth или .ScreenHeight свойства.

Пинч-контейнер, однако, так же, как и первоначально в рецепте, и все еще выходит за пределы.

ответ

0

Этот ответ, скорее всего, очень скоро для ваших нужд, Чет ... но вы можете просто обернуть все это в ScrollView (которое вы соответствующим образом определите местонахождение и/или размер для ваших нужд). Это должно работать должным образом.

<ScrollView Grid.Column="2" VerticalOptions="Start"> 
    <PanContainer> 
     <PanContainer.Content> 
     <Image x:Name="SomeImage" Aspect="AspectFit" /> 
     </PanContainer.Content> 
    </PanContainer> 
    </ScrollView> 

Cheers! Mike

+0

Нет, все в порядке. Stack Exchange все равно, если вы опубликуете новый ответ на старый вопрос, если ваш ответ будет порядочным. –

+0

Спасибо, но мне нужно было увеличить масштаб, а не просто прокручивать. Я закончил идти другим путем, чтобы выполнить свою задачу, но спасибо за эту идею. –

0

Недвижимость IsClippedToBounds, которая помогла мне с этой проблемой.

Например:

<PanContainer IsClippedToBounds="true"> 
    <PanContainer.Content> 
     <Image x:Name="SomeImage" /> 
    </PanContainer.Content> 
</PanContainer> 

Чтобы получить щепотку и панорамирование, вы можете либо обернуть пинч элемент в кастрюлю элемента, или наоборот, или вы можете создать отдельный класс с функциями как с щепоткой и классы пан. Последнее, вероятно, лучше.

Это само по себе не будет работать точно так, как вы ожидаете, потому что вычисления в функции щепотки и панорамирования не знакомы друг с другом, поэтому, если вы, например, зажимаете, чтобы увеличить масштаб, то функция панорамирования не знает, что это теперь может двигаться дальше.