为什么Xamarin IOS customrenderer中没有检测到长按开始/结束?

为什么Xamarin IOS customrenderer中没有检测到长按开始/结束?,ios,xamarin,xamarin.forms,uibutton,Ios,Xamarin,Xamarin.forms,Uibutton,我有一个Xamarin表单项目,其中我想有一个按钮,必须按下long才能触发事件。除了长按事件,我还需要按下按钮的确切时间,因为那时我想在UI上启动一些动画 我做了一个自定义的渲染器来解决这个问题,在Android上它可以工作,但在IOS上我有问题:有时候可以,有时候不行 在IOS上,我是这样做的:我使用触地事件获得触摸的准确时间,触地在末端,UILongPressGestureRecognitor长按。有时它像一个符咒,但有时只有UILongPressGestureRecognitor的事件在

我有一个Xamarin表单项目,其中我想有一个按钮,必须按下long才能触发事件。除了长按事件,我还需要按下按钮的确切时间,因为那时我想在UI上启动一些动画

我做了一个自定义的渲染器来解决这个问题,在Android上它可以工作,但在IOS上我有问题:有时候可以,有时候不行

在IOS上,我是这样做的:我使用触地事件获得触摸的准确时间,触地在末端,UILongPressGestureRecognitor长按。有时它像一个符咒,但有时只有UILongPressGestureRecognitor的事件在未触发着陆之前触发

这是我的密码:

[assembly: ExportRenderer(typeof(LongPressButton), typeof(LongPressButtonRenderer))]

 namespace AnyProj.iOS
{
public class LongPressButtonRenderer : ButtonRenderer
{
    private LongPressButton _longPressButton;

    private UILongPressGestureRecognizer _longPressGestureRecognizer;

    public LongPressButtonRenderer()
    {

    }

    protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
    {
        base.OnElementChanged(e);

        _longPressGestureRecognizer = new UILongPressGestureRecognizer(() => HandleLongPress());

        if(e.NewElement == null)
        {
            if (_longPressGestureRecognizer != null)
            {
                this.RemoveGestureRecognizer(_longPressGestureRecognizer);
            }
        }

        if(e.OldElement == null)
        {
            _longPressButton = (LongPressButton)e.NewElement;
            Control.TouchDown += (sender, ee) => {
                Debug.WriteLine("Sometimes triggered, sometimes not.");
            };
            Control.TouchUpInside += (sender, ee) => {
                Debug.WriteLine("Sometimes triggered, sometimes not.");
            };
            _longPressGestureRecognizer.MinimumPressDuration = 2.0;
            this.AddGestureRecognizer(_longPressGestureRecognizer);
        }
    }

    private void HandleLongPress()
    {
        try
        {
            if (_longPressGestureRecognizer.State == UIGestureRecognizerState.Began)
                Debug.WriteLine("Sometimes triggered, sometimes not.");
        }
        catch(Exception exc)
        {
            Debug.Assert(false,exc.Message);
        }
    }
}
}

}

我已经在我的项目中测试了以下代码,并且运行良好。在iphone5c物理设备上测试。请注意,如果长按开始,将不会调用
HandleTouchUpInside
;相反,您可以从
uiLongPressGestureRecognitizer
uiGestureRecognitizerState.Ended
状态确定结束

protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
{
    base.OnElementChanged(e);

    if (e.OldElement != null)
    {
        RemovePressEvents();
    }

    if (e.NewElement != null)
    {
        AddPressEvents();
    }
}

private void AddPressEvents()
{
    _longPressGestureRecognizer = new UILongPressGestureRecognizer(HandleLongPress);
    Control.TouchDown += HandleTouchDown;
    Control.TouchUpInside += HandleTouchUpInside;
    AddGestureRecognizer(_longPressGestureRecognizer);
}

private void RemovePressEvents()
{
    Control.TouchDown -= HandleTouchDown;
    Control.TouchUpInside -= HandleTouchUpInside;
    RemoveGestureRecognizer(_longPressGestureRecognizer);
}

private void HandleTouchDown(object sender, EventArgs e)
{
    System.Diagnostics.Debug.WriteLine("TOUCH DOWN");
}

private void HandleTouchUpInside(object sender, EventArgs e)
{
    // Note: will not be called if the Long Press begins. Instead,
    // You can determine the end of the press from when HandleLongPress
    // is called and UILongPressGestureRecognizer.State = 
    // UIGestureRecognizerState.Ended
    System.Diagnostics.Debug.WriteLine("TOUCH UP INSIDE");
}

private void HandleLongPress(UILongPressGestureRecognizer o)
{
    switch (o.State)
    {
        case UIGestureRecognizerState.Began:
            System.Diagnostics.Debug.WriteLine("LONG PRESS BEGAN");
            break;

        case UIGestureRecognizerState.Ended:
            System.Diagnostics.Debug.WriteLine("LONG PRESS ENDED");
            break;
    }
}
protected override void OnElementChanged(ElementChangedEventArgs e)
{
基础。一个要素发生变化(e);
if(e.OldElement!=null)
{
RemovePressEvents();
}
if(例如NewElement!=null)
{
AddPressEvents();
}
}
私有void AddPressEvents()
{
_longPressGestureRecognizer=新UILongPressGestureRecognizer(HandleLongPress);
Control.TouchDown+=HandleTouchDown;
Control.TouchUpInside+=把手端部;
AddGestureRecognizer(长按GestureRecognizer);
}
私有void RemovePressEvents()
{
Control.TouchDown-=HandleTouchDown;
Control.toucupinside-=把手端部;
移除测试识别器(_longpress gesture recognizer);
}
私有void HandleTouchDown(对象发送方,事件参数e)
{
系统。诊断。调试。写线(“触地”);
}
私有void HandleTouchUpInside(对象发送方,事件参数e)
{
//注意:如果长按开始,将不会调用。相反,
//您可以通过手动长按来确定压力机的末端
//被调用,UILongPressGestureRecognitor。状态=
//UIgestureRecognitzerState。结束
系统。诊断。调试。写入线(“内部润色”);
}
专用void HandleLongPress(UILongPress手势识别器o)
{
开关(o状态)
{
案例UIgestureRecognitizerState。开始时间:
系统。诊断。调试。写线(“长按开始”);
打破
案例UIgestureRecognitizerState。结束时间:
系统。诊断。调试。写入线(“长按结束”);
打破
}
}

您是否使用真实设备来测试此功能?我测试了你的代码,它总是运行良好。或者尝试使用
Control.addgestureRecognitizer(\u longPressgestureRecognitizer)。此外,如果
ui长按GestureRecognitizer
触发,
TouchUpInside
将不会触发。您可以使用
\u longpressurerecognizer.State==uigesturecognizerstate.end
捕获此信息。是的,我在真实设备(IPhone SE)上测试了它。在模拟器上它总是工作的。我会测试你的其他建议,谢谢!你的建议并没有解决我的问题,非常感谢,因为我无法重现你的问题,我想这是否是你的特定设备的问题。如果可能,您可以在其他设备上测试它。我在我的iPhone上运行它,一切都像一个魔咒。现在它在2台iPhone SE设备上进行了测试,这在两台设备上都发生了。
protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
{
    base.OnElementChanged(e);

    if (e.OldElement != null)
    {
        RemovePressEvents();
    }

    if (e.NewElement != null)
    {
        AddPressEvents();
    }
}

private void AddPressEvents()
{
    _longPressGestureRecognizer = new UILongPressGestureRecognizer(HandleLongPress);
    Control.TouchDown += HandleTouchDown;
    Control.TouchUpInside += HandleTouchUpInside;
    AddGestureRecognizer(_longPressGestureRecognizer);
}

private void RemovePressEvents()
{
    Control.TouchDown -= HandleTouchDown;
    Control.TouchUpInside -= HandleTouchUpInside;
    RemoveGestureRecognizer(_longPressGestureRecognizer);
}

private void HandleTouchDown(object sender, EventArgs e)
{
    System.Diagnostics.Debug.WriteLine("TOUCH DOWN");
}

private void HandleTouchUpInside(object sender, EventArgs e)
{
    // Note: will not be called if the Long Press begins. Instead,
    // You can determine the end of the press from when HandleLongPress
    // is called and UILongPressGestureRecognizer.State = 
    // UIGestureRecognizerState.Ended
    System.Diagnostics.Debug.WriteLine("TOUCH UP INSIDE");
}

private void HandleLongPress(UILongPressGestureRecognizer o)
{
    switch (o.State)
    {
        case UIGestureRecognizerState.Began:
            System.Diagnostics.Debug.WriteLine("LONG PRESS BEGAN");
            break;

        case UIGestureRecognizerState.Ended:
            System.Diagnostics.Debug.WriteLine("LONG PRESS ENDED");
            break;
    }
}