Reputation: 41
I'm new to Xamarin.Forms and I've been trying to make a simple program. I wanted to make a program where I could pan and zoom an image. I found code on this site to handle the pinch gesture and view scaling (https://developer.xamarin.com/guides/xamarin-forms/user-interface/gestures/pinch/). I then tried to use this code to extend a 'ScrollView' class.
When I run my code on iOS, it works fine in the simulator. (The scaling is a little clunky, but I don't know if its the simulator or the technique)
When I run my code on Android (both the simulator OR an actual device), the page only scrolls. On the simulator, I'm using the command key to invoke the pinch gesture. I see the appropriate interface for the pinch gesture come up, but it looks like the scroll view is intercepting the gesture as a pan gesture.
When I take the ScrollView class out the mix (and simply make it a ContentView class), the pinch gesture works fine on both platforms.
Any ideas?
Here's the code for my container (which is almost an exact copy of the code at the link above)
using System;
using Xamarin.Forms;
namespace ImageTest
{
public class PinchToZoomContainer : ScrollView
{
double currentScale = 1;
double startScale = 1;
double xOffset = 0;
double yOffset = 0;
public PinchToZoomContainer()
{
var pinchGesture = new PinchGestureRecognizer();
pinchGesture.PinchUpdated += OnPinchUpdated;
GestureRecognizers.Add(pinchGesture);
}
public 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(0.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;
}
}
}
}
Upvotes: 4
Views: 1547
Reputation: 141
The answer lays within working on the Android, IOS project.
Check out this guide: http://www.xamboy.com/2017/08/02/creating-a-zoomable-scrollview-in-xamarin-forms/
What is suggested is to create a render that android and ios platformsupport to beable to zoom in on the application on ScrollView.
Upvotes: 0