10

注意:我已经阅读了一些关于UIScrollView发送触摸到子视图的问题(包括,虽然我已经投票了,但它不再像我预期的那样工作了)。

我所拥有的:我有UIScrollView一个 Custom UIView(我们称之为A),里面覆盖了整个UIScrollView. 我也可以UIViewsA中放置其他自定义。

在我这样做的代码上:

[scrollView setDelaysContentTouches:YES];
scrollView.canCancelContentTouches = NO;

发生了什么:目前我唯一的问题是,如果我想在A中移动子视图,我必须触摸它,等待,然后再移动它。正是如此所述:

现在,行为会根据第一次触摸 UIView 的“时间长度”而改变。如果它很短,则管理相对拖动,因为它是 UIScrollView 的滚动。如果它很长,那么我会在我的 UIView 中得到 touchesMoved: 事件。

我想要什么:A中的子视图应该始终获得优先级,我不应该触摸和等待。如果我触摸A而不是它的子视图,我希望UIScrollView接收触摸,例如平移和移动(contentSize大于frame)。


编辑 1.0

我在泛型中拥有这个AUIScrollView视图的唯一原因是因为我希望能够放大/缩小A视图。所以我正在做以下事情:

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    return customView; // this is the A view
}

一开始我没有A视图,UIScrollView我唯一做的就是将A添加为我的UIViewController's根视图的子视图,一切都很顺利。如果有另一种启用放大/缩小的方法,我将很乐意接受答案。

4

4 回答 4

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]]);
}
于 2012-08-15T11:54:02.517 回答
4

我没有对此进行测试,但我相信您如何处理视图 A(或其子视图)中的触摸事件将决定如何传递触摸事件。具体来说,如果您尝试使用方法: touchesBegan, touchesMoves, touchesEnded, etc 而不是 aUIGestureRecognizer您将不会以您想要的方式接收触摸。Apple 设计UIGestureRecognizer用于处理您所面临的问题。具体来说,UIScrollView用于UIPanGestureRecognizer处理滚动。如果您将 a 添加UIPanGestureRecognizer到其中一个子视图上View A发生的任何“平移”的每个子视图,则应将其发送到该子视图而不是UIScrollView. 但是,如果您只是使用“原始”touches方法,则UIPanGestureRecognizerinUIScrollView将永远不会被取消。

通常,最好使用 aUIGestureRecognizer而不是直接在视图中处理触摸。如果您需要以没有标准UIGestureRecognizer可以提供的方式处理触摸,请子类UIGestureRecognizer化和处理那里的触摸。这样您就可以获得 a 的所有功能UIGestureRecognizer以及您自己的自定义触摸处理。我真的认为 Apple 打算UIGestureRecognizer替换开发人员使用的大部分(如果不是全部)自定义触摸处理代码UIView。它允许代码重用,并且在减轻哪些代码处理哪些触摸事件时更容易处理。

于 2012-08-14T12:01:43.853 回答
0

Jacky,我需要一个类似的东西:在一个建筑计划中(你的 A,在我的例子中是 UIScrollView 的一个子类),让用户放置和调整对象的大小(称之为 Bs)。这是我对这种行为的理解的草图:

  • 在superview的(A)initWithFrame:方法中,设置这两个:

    self.canCancelContentTouches = YES;
    self.delaysContentTouches = NO;
    

    这将确保 B 上的抽头立即路由到 B。

  • 在嵌入的 B 中,阻止超级视图 A 取消点击,因此它不会干扰在 B 上启动的手势。

    在该touchesBegan:方法中,向上搜索视图层次结构(使用视图superview的属性),直到找到 a UIScrollView,并将其设置canCancelContentTouchesNOtouchesEnded记住你改变的superview,在B的andtouchesCancelled方法中恢复这个属性。

我很想知道这是否也适合你。祝你好运!

野比

于 2012-08-14T09:25:08.313 回答
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 

希望帮助你

于 2012-08-14T10:20:59.760 回答