我有一个包含的UIImageView一个UIScrollView。 该UIScrollView的缩放让并通过的UIImageView平移。
问题是,我想知道的手指运动中每一次,我试图赶上与touchesMoved方法事件。 但它不工作,尽管和的touchesBegan touchesEnded被正确调用。
事实上,touchesMoved被称为如果手指运动是非常小的,而且UIScrollView的不开始平移。 当时的UIScrollView开始被移动的时刻,事件停止被调用。
有人知道是什么问题,如何解决? 我想,也许在里面的UIImageView是捕捉事件或类似的东西。
其实,这真是相当的问题,因为它的UIScrollView“ 吃 ” TouchesMoved事件(即使传播几个第一批)。
所以,我刚刚想出的办法直接从一个UIWindow获得的事件。 这是肯定不是在应用结构意义上的最好的办法,但在某些情况下定制(这正是我所需要的)的罚款。
(实例是在MonoTouch的C#)。
创建自定义的UIWindow(我这里不显示如何更换标准的UIWindow与mywindow的,由于我的自定义逻辑(使用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的),所以另外,如果你愿意,你可以取消该窗口的事件传播只是,如果你想防止任何其他处理程序,除了你的申请(您可以添加“处理”标志的处理程序,例如)。
尝试使用UIScrollViewDelegate跟踪与偏移改变或缩放比例的变化。
- (void)scrollViewDidScroll:(UIScrollView *)scrollView;
- (void)scrollViewDidZoom:(UIScrollView *)scrollView;
或检查zoomScale
价值变动UIScrollView
之间touchesBegan: & (touchesMoved: or touchesCancelled:) events
。
创建的UIScrollView类的子类,并重写的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];
}
}
滚动视图属性canCancelContentTouches = NO
允许触摸事件将被向上传递响应链。
请检查该识别触摸事件(开始,移动,结束)使用滚动型的移动手势,
Class CustomScrollView:UIScrollView
{
CustomScrollView()
{
(this.GestureRecognizers[1] as UIPanGestureRecognizer).AddTarget(() => this.PanHandle(this.GestureRecognizers[1] as UIPanGestureRecognizer));
}
private void PanHandle(UIPanGestureRecognizer gestureRecognizer)
{
var touchLocation=gestureRecognizer.LocationInView(this)
if (gestureRecognizer.State == UIGestureRecognizerState.Began)
{
//Touches began
}
else if (gestureRecognizer.State == UIGestureRecognizerState.Changed)
{
//Touches Moved
}
else if (gestureRecognizer.State == UIGestureRecognizerState.Ended)
{
//Touches ended
}
}
}
Regards,
Ashwin