Xamarin-捏缩放无法在IOS中使用。在Android上正常工作

问题描述 投票:0回答:1

我已使用SebasianKruse https://forums.xamarin.com/discussion/74168/full-screen-image-viewer-with-pinch-to-zoom-pan-to-move-tap-to-show-captions-for-xamarin-forms/p2在此处发布的代码来捏住缩放和平移我的图像。它在Android上效果很好,但在IOS中我无法缩放和平移。

我试图在OnPanUpdated内设置一个断点,但在IOS上从未达到过。

这是我的代码:

xaml:

    <AbsoluteLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
        <StackLayout
             AbsoluteLayout.LayoutFlags="All"
             AbsoluteLayout.LayoutBounds="0,0,1,1">
            <Service:PinchToZoomContainer HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
                <ffimageloading:CachedImage RetryCount="5" RetryDelay="1" CacheDuration="1" x:Name="MyImage" HorizontalOptions="Fill" VerticalOptions="CenterAndExpand" DownsampleToViewSize="False">
                </ffimageloading:CachedImage>                   
            </Service:PinchToZoomContainer>                
        </StackLayout>
        <StackLayout BindingContext="{x:Reference MyImage}" IsVisible="{Binding IsLoading}" Padding="12"
             AbsoluteLayout.LayoutFlags="PositionProportional"
             AbsoluteLayout.LayoutBounds="0.5,0.5,-1,-1">
            <ActivityIndicator BindingContext="{x:Reference MyImage}" IsRunning="{Binding IsLoading}" />
            <Label Text="Loading Hi-Res Image..." BindingContext="{x:Reference MyImage}" IsVisible="{Binding IsLoading}" HorizontalOptions="Center" TextColor="Black"/>
         </StackLayout>
    </AbsoluteLayout>     
</ContentPage.Content>

Service / PinchToZoomContainer.cs

using System;
using Xamarin.Forms;
using Xamarin.Forms.Internals;

namespace GalShare.Service
{
public class PinchToZoomContainer : ContentView
{
    private double _startScale, _currentScale;
    private double _startX, _startY;
    private double _xOffset, _yOffset;

    public double MinScale { get; set; } = 1;
    public double MaxScale { get; set; } = 4;

    public PinchToZoomContainer()
    {
        var tap = new TapGestureRecognizer { NumberOfTapsRequired = 2 };
        tap.Tapped += OnTapped;
        GestureRecognizers.Add(tap);

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

        var pan = new PanGestureRecognizer();
        pan.PanUpdated += OnPanUpdated;
        GestureRecognizers.Add(pan);
    }

    protected override void OnSizeAllocated(double width, double height)
    {
        RestoreScaleValues();
        Content.AnchorX = 0.5;
        Content.AnchorY = 0.5;

        base.OnSizeAllocated(width, height);
    }

    private void RestoreScaleValues()
    {
        Content.ScaleTo(MinScale, 250, Easing.CubicInOut);
        Content.TranslateTo(0, 0, 250, Easing.CubicInOut);

        _currentScale = MinScale;
        _xOffset = Content.TranslationX = 0;
        _yOffset = Content.TranslationY = 0;
    }

    private void OnTapped(object sender, EventArgs e)
    {
        if (Content.Scale > MinScale)
        {
            RestoreScaleValues();
        }
        else
        {
            //todo: Add tap position somehow
            StartScaling();
            ExecuteScaling(MaxScale, .5, .5);
            EndGesture();
        }
    }

    private void OnPinchUpdated(object sender, PinchGestureUpdatedEventArgs e)
    {
        switch (e.Status)
        {
            case GestureStatus.Started:
                StartScaling();
                break;

            case GestureStatus.Running:
                ExecuteScaling(e.Scale, e.ScaleOrigin.X, e.ScaleOrigin.Y);
                break;

            case GestureStatus.Completed:
                EndGesture();
                break;
        }
    }

    private void OnPanUpdated(object sender, PanUpdatedEventArgs e)
    {
        switch (e.StatusType)
        {
            case GestureStatus.Started:
                _startX = e.TotalX;
                _startY = e.TotalY;

                Content.AnchorX = 0;
                Content.AnchorY = 0;

                break;

            case GestureStatus.Running:
                var maxTranslationX = Content.Scale * Content.Width - Content.Width;
                Content.TranslationX = Math.Min(0, Math.Max(-maxTranslationX, _xOffset + e.TotalX - _startX));

                var maxTranslationY = Content.Scale * Content.Height - Content.Height;
                Content.TranslationY = Math.Min(0, Math.Max(-maxTranslationY, _yOffset + e.TotalY - _startY));

                break;

            case GestureStatus.Completed:
                EndGesture();
                break;
        }
    }

    private void StartScaling()
    {
        _startScale = Content.Scale;

        Content.AnchorX = 0;
        Content.AnchorY = 0;
    }

    private void ExecuteScaling(double scale, double x, double y)
    {
        _currentScale += (scale - 1) * _startScale;
        _currentScale = Math.Max(MinScale, _currentScale);
        _currentScale = Math.Min(MaxScale, _currentScale);

        var deltaX = (Content.X + _xOffset) / Width;
        var deltaWidth = Width / (Content.Width * _startScale);
        var originX = (x - deltaX) * deltaWidth;

        var deltaY = (Content.Y + _yOffset) / Height;
        var deltaHeight = Height / (Content.Height * _startScale);
        var originY = (y - deltaY) * deltaHeight;

        var targetX = _xOffset - (originX * Content.Width) * (_currentScale - _startScale);
        var targetY = _yOffset - (originY * Content.Height) * (_currentScale - _startScale);

        Content.TranslationX = targetX.Clamp(-Content.Width * (_currentScale - 1), 0);
        Content.TranslationY = targetY.Clamp(-Content.Height * (_currentScale - 1), 0);

        Content.Scale = _currentScale;
    }

    private void EndGesture()
    {
        _xOffset = Content.TranslationX;
        _yOffset = Content.TranslationY;
    }
}
}

为什么此代码在IOS上不起作用?根据上面论坛中其他用户的帖子,它在两种系统上均应工作。.

ios xamarin xamarin.forms pinchzoom gesture-recognition
1个回答
1
投票

尽管在真实的物理设备上进行测试不会有任何差异事件。

这是因为Xcode 11.4向UIGestureRecognizerDelegate和我们最初建议的默认值ShouldReceiveEvent与世界的配合不好。

我们的产品团队已在Xamarin.iOS 13.16.0.13中修复此问题:https://github.com/xamarin/Xamarin.Forms/issues/10162#issuecomment-607585466您可以在Mac上手动下载并安装pkg。但是Windows上的VS已经发布了新版本,现在我们只能在安装新的Xamarin iOS版本之后使用VS for Mac临时开发它。

© www.soinside.com 2019 - 2024. All rights reserved.