Ios 如何使用CGPoint获取UIScrollView的子视图

Ios 如何使用CGPoint获取UIScrollView的子视图,ios,objective-c,uiscrollview,Ios,Objective C,Uiscrollview,我有一个UIScrollView,其中有许多大小相等的矩形子视图。然后我需要能够将CGPoint传递给UIScrollView,我希望它给我一个包含CGPoint的矩形子视图。这基本上是hitTest:event,除了hitTest:event:一旦CGPoint超出了UIScrollView的范围,并且没有查看其实际内容,就不能与UIScrollView一起工作 大家都在做什么?如何在UIScrollView内容视图上“点击测试” 下面是一些代码来说明这个问题: NSArray *rectan

我有一个
UIScrollView
,其中有许多大小相等的矩形子视图。然后我需要能够将
CGPoint
传递给
UIScrollView
,我希望它给我一个包含
CGPoint
的矩形子视图。这基本上是
hitTest:event
,除了
hitTest:event:
一旦
CGPoint
超出了UIScrollView的范围,并且没有查看其实际内容,就不能与
UIScrollView
一起工作

大家都在做什么?如何在
UIScrollView
内容视图上“点击测试”

下面是一些代码来说明这个问题:

NSArray *rectangles = [self getBeautifulRectangles];

CGFloat rectangleLength;
rectangleLength = 100;

// add some rectangle subviews
for (int i = 0; i < rectangles.count; i++) {
    UIView *rectangle = [rectangles objectAtIndex:i];  
    [rectangle setFrame:CGRectMake(i * rectangleLength, 0, rectangleLength, rectangleLength)];
    [_scrollView addSubview:rectangle];
}
[_scrollView setContentSize:CGSizeMake(rectangleLength * rectangles.count, rectangleLength)];

// add scroll view to parent view
UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0,0,320, rectangleLength)];
[containerView addSubview:_scrollView];


// compute CGPoint to center of first rectangle
CGPoint number1RectanglePoint = CGPointMake(0 * rectangleLength + 50, 50);

// compute CGPoint to center of fifth rectangle
CGPoint number5RectanglePoint = CGPointMake(4 * rectangleLength + 50, 50);

UIView *firstSubview = [containerView hitTest:number1RectanglePoint withEvent:nil];
UIView *fifthSubview = [containerView hitTest:number5RectanglePoint withEvent:nil];

if (firstSubview) NSLog(@"first rectangle OK");
if (fifthSubview) NSLog(@"fifth rectangle OK");
NSArray*矩形=[self-getbeautiful矩形];
CGFloat矩形长度;
矩形长度=100;
//添加一些矩形子视图
对于(int i=0;i

输出:第一个矩形OK

我猜您将错误的
CGPoint
坐标传递到
hitTest:withEvent:
方法,如果滚动视图,将导致错误行为

传递给此方法的坐标必须位于目标视图坐标系中。我猜您的坐标位于
UIScrollView
的superview坐标系中

在将坐标用于命中测试之前,可以使用
CGPoint hitPoint=[scrollView convertPoint:yourPoint fromView:scrollView.superview]
转换坐标


在您的示例中,您让容器视图执行命中测试,但容器只能看到并命中滚动视图的可见部分,因此命中失败

要点击可见区域之外的滚动视图子视图,必须直接在滚动视图上执行点击测试:

UIView *firstSubview = [_scrollView hitTest:number1RectanglePoint withEvent:nil];
UIView *fifthSubview = [_scrollView hitTest:number5RectanglePoint withEvent:nil];

您应该能够循环浏览scrollview子视图

+(UIView *)touchedViewIn:(UIScrollView *)scrollView atPoint:(CGPoint)touchPoint {

    CGPoint actualPoint = CGPointMake(touchPoint.x + scrollView.contentOffset.x, scrollView.contentOffset.y + touchPoint.y);

    for (UIView * subView in scrollView.subviews) {
        if(CGRectContainsPoint(subView.frame, actualPoint)) {
            NSLog(@"THIS IS THE ONE");
            return subView;
        }

    }

    //Nothing touched
    return nil;
}

虽然看@fluidsonic的答案,他的计算
实际点更优雅,但我认为这不起作用。我已经在计算CGPoint相对于
UIScrollView
的坐标。此外,
hitTest:withEvent:
通常用于superview,并返回最远的子级
UIView
,userInteractionEnabled=YES。如果不查看代码,很难判断实现中的错误。请分享。我添加了一些代码供您查看。如果您认为还有其他方法可以让您的方法发挥作用,并避免像@Flexicoder建议的那样在滚动视图子视图中循环,请告诉我。我会选择最好的答案,还是不走运。看起来hitTest:withEvent:只关心UIView的边界。啊,没错。要改变这种行为,您必须对滚动视图进行子类化,并覆盖
pointInside:withEvent:
。如果点位于滚动视图的
contentSize
内,则返回
YES