WMios WMios - 4 months ago 69
Objective-C Question

Setting collision bounding path of a UIView in iOS 9

In iOS 9 Apple introduced the

collisionBoundsType
to
UIKit-Dynamics
.

I have no issue when setting this
UIDynamicItemCollisionBoundsTypeRectangle
or when I set this to
UIDynamicItemCollisionBoundsTypeEllipse
.

The screenshot below is from a game I am making where the
collisionBoundsType
of the player is set to rectangle and the ball is set to ellipse:

enter image description here

However, when I set the player's
collisionBoundsType
to path I get weird behavior as seen here:

enter image description here

The view appears higher than it should and the collision body is to the right of where it should be.

Currently I have
collisionBoundingPath
set to this:

- (UIBezierPath *)collisionBoundingPath
{
maskPath = [[UIBezierPath alloc] init];
[maskPath addArcWithCenter:CGPointMake(SLIME_SIZE, SLIME_SIZE) radius:SLIME_SIZE startAngle:0*M_PI endAngle:M_PI clockwise:NO];
return maskPath;
}


Additionally, my drawRect function looks like this:

- (void) drawRect:(CGRect)rect
{
if (!_color){
[self returnDefualtColor];
}
if (!maskPath) maskPath = [[UIBezierPath alloc] init];
[maskPath addArcWithCenter:CGPointMake(SLIME_SIZE, SLIME_SIZE) radius:SLIME_SIZE startAngle:0*M_PI endAngle:M_PI clockwise:NO];
[_color setFill];
[maskPath fill];
}


Why is this happening? How do I set the path of the collision body to be the same as the drawing in the view?

Additionally, the red is just the background of the view (i.e.
view.backgroundColor = [UIColor redColor];
).

Answer

From the documentation on the UIDynamicItem here, the following statement about the coordinate system for paths seems to represent what is wrong:

The path object you create must represent a convex polygon with counter-clockwise or clockwise winding, and the path must not intersect itself. The (0, 0) point of the path must be located at the center point of the corresponding dynamic item. If the center point does not match the path’s origin, collision behaviors may not work as expected.

Here it states that the (0,0) for the path MUST be the center point.

I would think that the center of your arc path should be (0,0) and not (SLIME_SIZE/2,SLIME_SIZE/2). Have you perhaps set the width and height of the UIView frame to SLIME_SIZE rather than SLIME_SIZE*2?

SLIME_SIZE really seems to define the radius, so the frame width should be SLIME_SIZE*2. If it is set as SLIME_SIZE, then that would explain why you need to translate by SLIME_SIZE/2 as a correction.