在iOS中的父级自定义控件中禁用手势

时间:2019-02-18 14:25:07

标签: ios xamarin.forms gesture-recognition skiasharp

我有一个用于控制手势的自定义控件“容器”,以及一个内部的Skiasharp可绘制控件。我要寻找的功能是,在第一步中,用户可以缩放/移动容器内的图像,然后禁用容器的手势,并且用户可以用手指绘制可见图像。它曾经可以工作几个月,但是当移至xamarin 3.x时,它开始失败。

这是容器的代码

public class GestureContainer : ContentView
{
    private const double MIN_SCALE = 1;
    private const double MAX_SCALE = 4;
    private double startScale, currentScale;
    private double startX, startY;
    private double xOffset, yOffset;

    private PanGestureRecognizer pan;
    private PinchGestureRecognizer pinchGesture;
    private TapGestureRecognizer tap;

    public static readonly BindableProperty GestureOnProperty =
       BindableProperty.Create("GestureOn", typeof(bool), typeof(GestureContainer), defaultValue: true, defaultBindingMode: BindingMode.TwoWay, propertyChanged: GestureOnChanges);

    public bool GestureOn
    {
        get
        {
            return (bool)GetValue(GestureOnProperty);
        }
        set
        {
            SetValue(GestureOnProperty, value);
        }
    }


    private static void GestureOnChanges(BindableObject bindable, object oldvalue, object newvalue)
    {
        GestureContainer gestureContainer = bindable as GestureContainer;

        if ((bool)newvalue)
            gestureContainer.SetGestures();
        else
            gestureContainer.GestureRecognizers.Clear();

    }


    public GestureContainer()
    {
        pinchGesture = new PinchGestureRecognizer();
        pan = new PanGestureRecognizer();
        tap = new TapGestureRecognizer { NumberOfTapsRequired = 2 };

        SetGestures();

        Scale = MIN_SCALE;
        TranslationX = TranslationY = 0;
    }

    private void SetGestures()
    {
        pinchGesture.PinchUpdated += OnPinchUpdated;
        GestureRecognizers.Add(pinchGesture);

        pan.PanUpdated += OnPanUpdated;
        GestureRecognizers.Add(pan);

        tap.Tapped += OnTapped;
        GestureRecognizers.Add(tap);
    }

    private void OnTapped(object sender, EventArgs e)
    {
       /**/
    }

    void RestoreScaleValues()
    {
        /**/
    }

    void OnPinchUpdated(object sender, PinchGestureUpdatedEventArgs e)
    {
       /**/
    }

    void OnPanUpdated(object sender, PanUpdatedEventArgs e)
    {
       /**/
    }
}

具有“怪异”功能的部分是这样的:

gestureContainer.GestureRecognizers.Clear();

当我将binded属性设置为false时,将调用该方法,并调用.Clear(),但是无论捏/平移/敲击仍在起作用,这都会导致绘图无法正常工作< / p>

编辑

这是XAML代码

<controls:GestureContainer GestureOn="{Binding OptionsVisibility, Converter={StaticResource BooleanConverter}}"  AbsoluteLayout.LayoutBounds="0,0,1,1" AbsoluteLayout.LayoutFlags="All">
                <controls:GestureContainer.Content>
                    <Grid>
                        <ffimageloading:CachedImage  
                            Rotation="{Binding Rotation}"  
                            x:Name="originalView"
                            Aspect="AspectFit"
                            DownsampleToViewSize="True"
                            Source="{Binding Imagen.ImageStream}"/>
                        <Grid IsEnabled="{Binding OptionsVisibility}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="Transparent">
                            <controls:BindableSKCanvasView x:Name="canvasView"
                                       Color="{Binding StrokeColor}"
                                       WidthStroke="{Binding StrokeWidth}"
                                       EnableTouchEvents="True"
                                       PaintSurface="OnCanvasViewPaintSurface" />
                            <Grid.Effects>
                                <skiacontrols:TouchEffect Capture="True" TouchAction="OnTouchEffectAction" />
                            </Grid.Effects>
                        </Grid>

                    </Grid>
                </controls:GestureContainer.Content>
            </controls:GestureContainer>

2 个答案:

答案 0 :(得分:0)

似乎正在创建多个引用。

尝试编写这样的函数

void clearGesture() {
  pinchGesture.PinchUpdated -= OnPinchUpdated;
  pan.PanUpdated -= OnPanUpdated;
  tap.Tapped -= OnTapped;
}

并像gestureContainer.clearGesture();

这样明确地称呼它

答案 1 :(得分:0)

我认为您错过的要点:

  • 使用nameof(PropertyName)代替"PropertyName",因为它可以帮助我们忽略人为错误,例如:拼写错误。

  • 在设置器中调用OnPropertyChanged方法,以确保您不会错过PropertyChanged事件。

  • 在构造函数上调用基类实现,只是为了确保一切正常。(只是一种习惯,我不认为这是强制性的)

因此,我进行了必要的更改,可以在下面找到它们,我已经对其进行了更改,可以在下面找到它们

 public class GestureContainer : ContentView   
 {
    private const double MIN_SCALE = 1;
    private const double MAX_SCALE = 4;
    private double startScale, currentScale;
    private double startX, startY;
    private double xOffset, yOffset;

    private PanGestureRecognizer pan;
    private PinchGestureRecognizer pinchGesture;
    private TapGestureRecognizer tap;

    public static readonly BindableProperty GestureOnProperty =
       BindableProperty.Create(nameof(GestureOn), typeof(bool), typeof(GestureContainer),
           defaultValue: true, defaultBindingMode: BindingMode.TwoWay, propertyChanged: GestureOnChanges);

    private static void GestureOnChanges(BindableObject bindable, object oldValue, object newValue)
    {
        GestureContainer gestureContainer = bindable as GestureContainer;

        if ((bool)newValue)
        {
            gestureContainer.SetGestures();
        }
        else
        {
            gestureContainer.GestureRecognizers.Clear();
        }
    }

    public bool GestureOn
    {
        get
        {
            return (bool)GetValue(GestureOnProperty);
        }
        set
        {
            SetValue(GestureOnProperty, value);
            OnPropertyChanged(nameof(GestureOn));
        }
    }

    public GestureContainer() : base()
    {
        pinchGesture = new PinchGestureRecognizer();
        pan = new PanGestureRecognizer();
        tap = new TapGestureRecognizer { NumberOfTapsRequired = 2 };

        SetGestures();

        Scale = MIN_SCALE;
        TranslationX = TranslationY = 0;
    }

    private void SetGestures()
    {
        pinchGesture.PinchUpdated += OnPinchUpdated;
        GestureRecognizers.Add(pinchGesture);

        pan.PanUpdated += OnPanUpdated;
        GestureRecognizers.Add(pan);

        tap.Tapped += OnTapped;
        GestureRecognizers.Add(tap);
    }

    private void OnTapped(object sender, EventArgs e)
    {
        /**/
    }

    private void RestoreScaleValues()
    {
        /**/
    }

    private void OnPinchUpdated(object sender, PinchGestureUpdatedEventArgs e)
    {
        /**/
    }

    private void OnPanUpdated(object sender, PanUpdatedEventArgs e)
    {
        /**/
    }
}