Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

objective c - UIScrollView with touchesMoved not called

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

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.

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.

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

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.

(Examples are in MonoTouch C#).

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
}

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).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...