UIScrollView的与touchesMoved不叫(UIScrollView with tou

2019-06-27 18:17发布

我有一个包含的UIImageView一个UIScrollView。 该UIScrollView的缩放让并通过的UIImageView平移。

问题是,我想知道的手指运动中每一次,我试图赶上与touchesMoved方法事件。 但它不工作,尽管和的touchesBegan touchesEnded被正确调用。

事实上,touchesMoved被称为如果手指运动是非常小的,而且UIScrollView的不开始平移。 当时的UIScrollView开始被移动的时刻,事件停止被调用。

有人知道是什么问题,如何解决? 我想,也许在里面的UIImageView是捕捉事件或类似的东西。

Answer 1:

其实,这真是相当的问题,因为它的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的),所以另外,如果你愿意,你可以取消该窗口的事件传播只是,如果你想防止任何其他处理程序,除了你的申请(您可以添加“处理”标志的处理程序,例如)。



Answer 2:

尝试使用UIScrollViewDelegate跟踪与偏移改变或缩放比例的变化。

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

或检查zoomScale价值变动UIScrollView之间touchesBegan: & (touchesMoved: or touchesCancelled:) events



Answer 3:

创建的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];
    }
}


Answer 4:

滚动视图属性canCancelContentTouches = NO允许触摸事件将被向上传递响应链。



Answer 5:

请检查该识别触摸事件(开始,移动,结束)使用滚动型的移动手势,

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


文章来源: UIScrollView with touchesMoved not called