在UIScrollView上打开/关闭缩放并将事件传递到子视图

时间:2014-01-12 21:35:47

标签: ios objective-c uiview uiscrollview hittest

我正在制作一个类似“油漆”的应用程序,允许用户在图像上进行徒手绘图。它基于Nathanial Woolls的the SimpleDrawing app

用户还应该能够平移和缩放。所以我有一个按钮可以打开/关闭变焦。当变焦打开时,屏幕上的双击应该变焦,单触摸拖动应该平移。关闭时,活动绘图工具会对图像起作用。

这是我的视图层次结构:

- ViewController.view
 |- Top toolbar
 |- bottom toolbar
 |- scroll view
   |- drawingView
     |- N other views depending on elements user adds
     |- ...

滚动视图可以处理平移和缩放:

-(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale
{
     [drawingView setNeedsDisplay];
     [scrollView setNeedsDisplay];
}

-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
     return drawingView;
}

要打开/关闭变焦,我设置其最小/最大缩放比例属性(均为1以关闭,以及0.5 / 3以打开)以及userInteractionEnabled属性。

负责处理图纸视图上的触摸事件并激活绘图工具的响应者是视图控制器。

这是我的问题:当视图不可缩放时,拖动手势应该传递到“叶节点”视图。 drawingView具有像UITextField s这样的子视图,用户可以将其添加到要绘制的图形中,或者UIImageView用于插入预设符号。当缩放关闭时,用户应该能够拖动这些元素。但是,如果我将scrollView的userInteractionEnabled属性设置为NO,则所有拖动手势都由视图控制器处理(从而激活当前绘图工具),但如果我将其保留在YES上当缩放关闭时,它会阻止视图控制器执行任何操作,屏幕上的任何拖动都会平移视图。

我对命中测试和响应者链的理解

我一直在阅读Apple's documentation on Event Handling以了解这个过程。我对文档的理解是,当触摸发生时,系统将“沿着视图层次结构走下去”,寻找被触摸的“叶子节点”视图(命中测试过程);然后从该视图开始,它“走上”响应者链以找到可以处理该事件的响应者。我的理解是,如果在命中测试过程中的某个时刻,系统找到userInteractionEnabled设置为NO的视图,它将停在那里并从那里开始向上走响应链。它是否正确?在这种情况下,为什么当scrollView的userInteractionEnabledYES时,scrollView处理拖动事件而不是其子视图(因为drawingView的所有子视图都实现touchesMoved:withEvent)?

1 个答案:

答案 0 :(得分:0)

当您禁用缩放时,您还应禁用滚动,这将停止平移发生。无需将userInteractionEnabled设置为NO。而是scrollView.scrollEnabled = NO