0

所以我有一个可变数组,其中包含几个 UIViews 圆圈。现在我已经开始像这样设置方法了。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];

    CGPoint touchLocation = [touch locationInView:self.view];

    for (Circle *circle in playerOneCircles)
    {
        if ([circle.layer.presentationLayer hitTest:touchLocation])
        {
            [circle playerTap:nil];
            break;
        } 
    }   
}

这很好用。但它给出了重叠视图的问题。我希望其他 UIviews 也响应 touchesbegan 方法(然后会触发其他方法)。但如果 2 个对象重叠,那么我的 touchesbegan 会触发错误的方法。

所以我想定义多个只响应某些对象而不是anyObject的UITouch。我将如何将 UITouch 定义为使用可变数组中的对象?

4

1 回答 1

1

EDIT

Added comments to answer your comment to explain the code.

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    // We want to find all the circles that contain the touch point.
    // A circle does not have to be "on top" (or even visible) to be touched.
    // All circles that contain the touch point will be added to the touchedCircles set.
    NSMutableSet *touchedCircles = [NSMutableSet set];

    // To support multiple touches, we have to look at every touch object.
    for (UITouch *touch in touches) {
        CGPoint touchLocation = [touch locationInView:self.view];
        // Search through our collection of circle objects.  Any circle that
        // contains this touch point gets added to our collection of touched
        // circles.  If you need to know which UITouch is "touching" each circle,
        // you will need to store that as well.
        for (Circle *circle in playerOneCircles) {
            if ([circle containsPoint:touchLocation]) {
                [touchedCircles addObject:circle];
            }
        }
    }

    // We have completed our search for all touches and all circles.  If
    // and circle was touched, then it will be in the set of touchedCircles.
    if (touchedCircles.count) {
        // When any circle has been touched, we want to call some special method
        // to process the touched circle.  Send the method the set of circles, so it
        // knows which circles were touched.
        [self methodAWithTouchedCircles:touchedCircles];
    } else {
        // None of our circles were touched, so call a different method.
        [self methodB];
    }
}

You would implement containsPoint for a Circle something like this...

- (BOOL)containsPoint:(CGPoint)point
{
    // Since each of our objects is a circle, to determine if a point is inside
    // the circle, we just want to know if the distance between that point and
    // the center of the circle is less than the radius of the circle.
    // If your circle is really contained inside a view, you can compute the radius
    // as one-half the width of the frame.
    // Otherwise, your circle may actually have its own radius property, in which case
    // you can just use the known radius.
    CGFloat radius = self.frame.size.width *.5;

    // This is just the Pythagorean Theorem, or instance formula.
    // distance = sqrt((x0-x1)^2 + (y0-y1)^2)
    // and we want to check that
    //     distance < radius
    // By simple algebra, that is the same as checking
    //     distance^2 < radius^2
    // which saves us from having to compute the square root.
    CGFloat diffX = self.center.x - point.x;
    CGFloat diffY = self.center.y - point.y;
    return (diffX*diffX) + (diffY*diffY) < radius*radius;
}
于 2012-04-24T17:07:42.963 回答