注意:我已经阅读了一些关于UIScrollView
发送触摸到子视图(this所包含的内容的问题,虽然我已经投了票,但它还没有工作正如我打算的那样)。
我拥有的内容:我有一个UIScrollView
,其中包含自定义UIView
(让我们称之为 A )整个UIScrollView
。我也可以将其他自定义UIViews
放入 A 。
关于我正在执行此操作的代码:
[scrollView setDelaysContentTouches:YES];
scrollView.canCancelContentTouches = NO;
发生了什么:目前我的唯一问题是,如果我想在 A 中移动子视图,我必须触摸它,等待,然后移动它。正如所述here:
现在,行为的变化取决于"时间长度"的 首先触摸UIView。如果它很短,那么相对拖动 管理,因为它是UIScrollView的滚动。如果它很长,那么 我在UIView中获取了touchesMoved:事件。
我想要的是什么 A 中的子视图应始终获得优先权,我不应该触摸和等待。如果我触摸 A 而不是其子视图,我希望UIScrollView
接收触摸,例如平移和移动(contentSize
大于{{1} }})。
修改1.0
我在通用frame
中拥有此 A 视图的唯一原因是因为我希望能够放大/缩小 A 查看。所以我正在做以下事情:
UIScrollView
一开始我没有- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return customView; // this is the A view
}
内的 A 视图,我唯一做的就是将 A 添加为子视图我的UIScrollView
根视图,一切顺利。 如果还有其他方法可以启用放大/缩小功能,我很乐意接受答案。
答案 0 :(得分:8)
注意:感谢大家的贡献,特别是对Aaron Hayman的贡献。
我能够通过在UIScrollView
子类上执行以下操作来解决这个问题:
-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
CGPoint pointOfContact = [gestureRecognizer locationInView:self];
// The view with a tag of 200 is my A view.
return (![[self hitTest:pointOfContact withEvent:nil] isEqual:[self viewWithTag:200]]);
}
答案 1 :(得分:4)
我没有对此进行过测试,但我相信您在View A(或其子视图)中处理触摸事件的方式将决定触摸事件的传递方式。具体来说,如果您尝试使用这些方法:touchesBegan
,touchesMoves
,touchesEnded
等,而不是UIGestureRecognizer
,那么您将无法接触到的方式想。 Apple设计UIGestureRecognizer
来处理你所面临的问题。具体来说,UIScrollView
使用UIPanGestureRecognizer
来处理滚动。如果您为UIPanGestureRecognizer
的每个子视图添加View A
,则应将其中一个子视图发送到该子视图而不是UIScrollView
。但是,如果您只是使用“原始”touches
方法,UIPanGestureRecognizer
中的UIScrollView
将永远不会被取消。
通常,最好使用UIGestureRecognizer
而不是直接在视图中处理触摸。如果您需要以没有标准UIGestureRecognizer
可以提供的方式处理的触摸,则继承UIGestureRecognizer
并处理那里的触摸。这样,您就可以获得UIGestureRecognizer
的所有功能以及您自己的自定义触摸处理功能。我真的认为Apple希望UIGestureRecognizer
替换大多数(如果不是全部)开发人员在UIView
上使用的自定义触摸处理代码。它允许代码重用,并且在减轻代码处理触摸事件时处理起来要容易得多。
答案 2 :(得分:0)
Jacky,我需要类似的东西:在建筑计划(你的A,在我的例子中是UIScrollView的子类)中,让用户放置并调整对象大小(称之为Bs)。以下是我采取这种行为的原因草图:
在superview的(A)initWithFrame:
方法中,设置以下两个:
self.canCancelContentTouches = YES;
self.delaysContentTouches = NO;
这将确保B上的分接头立即路由到Bs。
在嵌入式B中,停止超级视图A取消点击,因此它不会干扰在B上开始的手势。
在touchesBegan:
方法中,向上搜索视图层次结构(使用视图的superview
属性),直到找到UIScrollView
,并将其canCancelContentTouches
设置为{{ 1}}。请记住您更改的超级视图,并使用B的NO
和touchesEnded
方法恢复此属性。
我对这是否也适合您感兴趣。祝你好运!
比康夫
答案 3 :(得分:0)
我认为你最好用“touchesBegan,touchesMoved,touchesEnded”来传递这个事件。
你可以这样做:你应该制作一个mainView。它有2个属性。一个是yourScrollView A,一个是yourCustomView。
`[yourScrollView addSubviews:yourCustomView];
[mainView addSubviews:yourScrollView];`
然后在mainView.m中编写你的touches方法就像这样(忽略scrollView语句)
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *mytouch=[[touches allObjects] objectAtIndex:0];
if ([[touches allObjects] isKindOfClass:[yourCustomView class]])
{
//do whatever you want
}
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *mytouch=[[touches allObjects] objectAtIndex:0];
if ([[touches allObjects] isKindOfClass:[yourCustomView class]])
{
//do whatever you want
}
}
最后一步:将事件传递给scrollView(您的A)的子视图。
#import "yourScrollView.h"
@implementation yourScrollView
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
// Initialization code.
}
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[super touchesBegan:touches withEvent:event];
if(!self.dragging)
[[self nextResponder] touchesBegan:touches withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
[super touchesMoved:touches withEvent:event];
if(!self.dragging)
[[self nextResponder] touchesMoved:touches withEvent:event];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
[super touchesEnded:touches withEvent:event];
if(!self.dragging)
[[self nextResponder] touchesEnded:touches withEvent:event];
}
- (void)dealloc {
[super dealloc];
}
@end
希望能帮到你