5

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

问题是我每次都想知道手指的运动,我试图用 touchesMoved 方法来捕捉事件。但它不起作用,尽管正确调用了 touchesBegan 和 touchesEnded 。

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

有人知道问题出在哪里以及如何解决吗?我想也许里面的 UIImageView 正在捕捉事件或类似的东西。

4

5 回答 5

1

实际上,这确实是一个相当大的问题,因为UIScrollView 确实”了TouchesMoved事件(即使传播了几个第一个事件)。

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

(示例在MonoTouch C#中)。

创建您的自定义 UIWindow(由于我的自定义逻辑(使用 MvvmCross 框架),我没有在这里展示如何用 MyWindow 替换标准 UIWindow,但这很容易并且通常在 appDelegate 初始化逻辑中完成 - 您会在 google/stack 溢出中发现):

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),所以如果你愿意,你可以取消窗口的事件传播,只有当你想阻止除你的之外的任何其他处理程序应用时(你可以添加“例如,处理程序的“已处理”标志)。

于 2013-08-01T12:25:59.723 回答
1

scrollview 属性canCancelContentTouches = NO允许将触摸事件向上传递到响应者链。

于 2012-11-14T14:14:56.303 回答
0

创建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];
    }
}
于 2012-09-04T08:26:11.367 回答
0

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

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

或者检查之间的zoomScale值变化。UIScrollViewtouchesBegan: & (touchesMoved: or touchesCancelled:) events

于 2014-01-20T02:44:57.543 回答
-1

请检查此项以使用滚动视图的平移手势识别触摸事件(开始、移动、结束),

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
于 2018-10-11T02:39:46.863 回答