带有touchesMoved的UIScrollView不被调用

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

问题是,我想每次都知道手指的动作,而我正在试着用touchesMoved方法来捕捉事件。 但它不工作,尽pipetouchesBegan和touchesEnded被调用正确。

实际上,如果手指运动非常小,则调用touchesMoved,并且UIScrollView不会开始平移。 在UIScrollView开始移动的时刻,事件停止被调用。

有人知道有什么问题,以及如何解决这个问题? 我以为也许里面的UIImageView捕捉事件或类似的东西。

尝试使用UIScrollViewDelegate跟踪偏移更改或缩放比例更改。

- (void)scrollViewDidScroll:(UIScrollView *)scrollView; - (void)scrollViewDidZoom:(UIScrollView *)scrollView; 

或者在touchesBegan: & (touchesMoved: or touchesCancelled:) events之间检查UIScrollViewzoomScale值更改。

创buildUIScrollView类的子类并覆盖touchesBegan:和其他触摸方法,如下所示:

 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { // If not dragging, send event to next responder if (!self.dragging) { [self.nextResponder touchesBegan: touches withEvent:event]; } else { [super touchesEnded: touches withEvent: event]; } } -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { // If not dragging, send event to next responder if(!self.dragging) { [self.nextResponder touchesBegan: touches withEvent:event]; } else { [super touchesEnded: touches withEvent: event]; } } -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { // If not dragging, send event to next responder if (!self.dragging) { [self.nextResponder touchesBegan: touches withEvent:event]; } else { [super touchesEnded: touches withEvent: event]; } } 

其实,这真的是一个问题,因为UIScrollViewTouchesMoved事件(即使传播了几个第一个)。

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

(例子在MonoTouch C#中 )。

创build你的自定义UIWindow (我没有在这里展示如何用MyWindowreplace标准的UIWindow,因为我的自定义逻辑(使用MvvmCross框架),但是这很容易,通常在appDelegate初始化逻辑中完成 – 你会发现在谷歌/堆栈溢出):

 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; } } 

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

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

处理程序喜欢(这是你自己的):

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

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

scrollview属性canCancelContentTouches = NO允许触摸事件通过响应者链传递。

Interesting Posts