没有调用touchesMoved的UIScrollView [英] UIScrollView with touchesMoved not called

查看:138
本文介绍了没有调用touchesMoved的UIScrollView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含UIImageView的UIScrollView。
UIScrollView允许通过UIImageView进行缩放和平移。

I've a UIScrollView that contains an UIImageView. The UIScrollView lets zooming and panning through the UIImageView.

问题是我想知道每次手指移动,我想抓住使用touchesMoved方法的事件。
但它没有用,尽管touchesBegan和touchesEnded被正确调用。

The problem is that I would like know the finger movement every time, and I'm trying to catch the event with touchesMoved method. But it's not working, despite touchesBegan and touchesEnded that are called correctly.

事实上,如果手指移动非常小,则调用touchesMoved,并且UIScrollView没有开始平移。在UIScrollView开始移动的那一刻,事件停止被调用。

In fact, touchesMoved is called if the finger movement is really small, and the UIScrollView doesn't started panning. At the moment that UIScrollView starts getting moved, the event stops being called.

有人知道问题是什么以及如何修复它?
我以为可能内部的UIImageView正在捕捉事件或类似事件。

Somebody know what's the problem and how to fix it? I've thought that maybe the UIImageView inside is catching the event or something like that.

推荐答案

实际上,那是非常有问题,因为 UIScrollView TouchesMoved 事件(即使先传播几个事件)。

Actually, that's really quite a problem, as the UIScrollView does "eat" TouchesMoved events (even if propagates several first ones).

所以,我刚刚提出了直接从UIWindow 获取事件的方法。这肯定不是应用程序结构意义上的最佳方法,但在某些自定义情况下(这正是我需要的)很好。

So, I've just come up with the approach to get the events directly from UIWindow. That's for sure not the best approach in the application structure sense, but in some custom situation (which was exactly what I needed) is fine.

(示例在 MonoTouch C#)。

创建自定义UIWindow (我不会在此处显示如何将标准UIWindow替换为MyWindow到期到我的自定义逻辑(使用MvvmCross框架),但这很简单,通常在appDelegate初始化逻辑中完成 - 你会发现在google / stack overflow中:

Create your custom UIWindow (I don't show here how to replace standard UIWindow with MyWindow due to my custom logic (using MvvmCross framework), but that's pretty easy and usually done in appDelegate initialization logic - you will find that in google/stack overflow):

public class MyWindow : UIWindow
{
    public MyWindow(RectangleF bounds) : base(bounds)
    {

    }

    public override void SendEvent(UIEvent evt)
    {
        if (evt.Type == UIEventType.Touches) {
            var el = (UITouch)evt.AllTouches.AnyObject;

            if (el.Phase == UITouchPhase.Began)
            {
                if(OnTouchBegan != null)
                    OnTouchBegan(el.View, new TouchCommandArgs(evt.AllTouches, evt));
            }

            if (el.Phase == UITouchPhase.Moved)
            {
                if(OnTouchMoved != null)
                    OnTouchMoved(el.View, new TouchCommandArgs(evt.AllTouches, evt));
            }

            if (el.Phase == UITouchPhase.Ended)
            {
                if(OnTouchEnd != null)
                    OnTouchEnd(el.View, new TouchCommandArgs(evt.AllTouches, evt));
            }

            if (el.Phase == UITouchPhase.Cancelled)
            {
                if(OnTouchCancel != null)
                    OnTouchCancel(el.View, new TouchCommandArgs(evt.AllTouches, evt));
            }

        } else
            MvxTrace.Trace (evt.Type == null ?  "-" : evt.ToString ());
        base.SendEvent(evt);
    }

    public event TouchCommand OnTouchBegan;
    public event TouchCommand OnTouchEnd;
    public event TouchCommand OnTouchCancel;
    public event TouchCommand OnTouchMoved;

}

public class TouchCommandArgs : EventArgs
{
    public NSSet Touches { get; set; }
    public UIEvent Evt { get; set; }

    public TouchCommandArgs(NSSet touches, UIEvent evt)
    {
        Touches = touches;
        Evt = evt;
    }
}

并在处理事件的地方订阅自定义事件处理程序

and in the place to handle the events subscribe for the custom events handlers:

var window = (MyWindow) UIApplication.SharedApplication.KeyWindow;
window.OnTouchBegan += view_OnTouchBegan;
window.OnTouchMoved += view_OnTouchMoved;
window.OnTouchCancel += view_OnTouchCancel;
window.OnTouchEnd += view_OnTouchEnd;

处理程序(这些都是你自己的):

handlers like (that's all by your own):

void view_OnTouchBegan(object sender, TouchCommandArgs args)
{
    // do your logic
}






在这种情况下,事件将同时处理(在两个地方:你的和UIScrollView),另外,如果你愿意,你可以取消窗口的事件传播,只有当你想要阻止任何其他处理程序除了你的处理器之外(例如你可以为你的处理程序添加Handled标志)。


In that case the events will be handling simultaneously (in both places: yours and UIScrollView), so additionally if you want, you can cancel the window's event propagation only if you want to prevent any other handlers to apply except yours (you can add "Handled" flag to your handlers, for instance).

这篇关于没有调用touchesMoved的UIScrollView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆