简体   繁体   English

如何在 xamarin.forms 的内容页面上启用放大和缩小?

[英]How to enable zoom in and zoom out on a contentpage in xamarin forms?

How can I enable zoom on a contentpage in xamarin.forms?如何在 xamarin.forms 的内容页面上启用缩放? Is it possible to enable it on the entire contentpage?是否可以在整个内容页面上启用它? Or is it only possible to zoom in on images?还是只能放大图片?

You can use the pinch gesture inside a ContentPage , here is the official page:您可以在ContentPage使用捏合手势,这是官方页面:

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

and for the entire project sample:对于整个项目示例:

https://github.com/xamarin/xamarin-forms-samples/tree/master/WorkingWithGestures/PinchGesture https://github.com/xamarin/xamarin-forms-samples/tree/master/WorkingWithGestures/PinchGesture

Here is an example of what you can achieve:以下是您可以实现的示例:

Xamarin.Forms Pinch Example Xamarin.Forms 捏合示例

Try this Class , this solution do not scroll when you zoom .试试这个类,这个解决方案在你缩放时不会滚动。 Source found here: Source Code来源在这里: 源代码

    public class PinchToZoomContainer : ContentView {
    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;
        }
    }
}

Helper DoubleExtensions辅助双重扩展

    public static class DoubleExtensions
{
    public static double Clamp (this double self, double min, double max)
    {
        return Math.Min (max, Math.Max (self, min));
    }
}

You can try using the Scale Api on the Content page.您可以尝试使用内容页面上的 Scale Api。 This seemed to work for me on a small test app.这似乎在一个小型测试应用程序上对我有用。

public App ()
{
    // The root page of your application
    var scaleUp = new Button {
        Text = "Scale Up"
    };
    scaleUp.Clicked += (sender, e) => {
        this.MainPage.Scale += 1;
    };

    var scaleDown = new Button {
        Text = "Scale Down"
    };
    scaleDown.Clicked += (object sender, EventArgs e) => {
        this.MainPage.Scale -= 1;
    };

    MainPage = new ContentPage {
        Content = new StackLayout {
            VerticalOptions = LayoutOptions.Center,
            Children = {
                scaleUp,
                scaleDown

            }
        }
    };
}

之前

之后

Trying to use this in conjunction with other controls that take the Pan/scroll gesture seems to fail.尝试将其与其他采用平移/滚动手势的控件结合使用似乎会失败。 ScrollView and ListView for example grab the Pinch gesture even though they themselves don't Pinch but they do scroll/pan.例如,ScrollView 和 ListView 会抓取捏合手势,即使它们本身不捏合但会滚动/平移。 So it seems like Pinch inherits/uses that gesture so it is grabbed by the wrapped control.所以看起来 Pinch 继承/使用了那个手势,所以它被包裹的控件抓住了。 This seems to make Pinch a very niche feature that can only work on very static views of Label and Image for example, but nothing more complex.这似乎使 Pinch 成为一个非常小众的功能,仅适用于 Label 和 Image 的 static 视图,但没有比这更复杂的了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM