Reputation: 1500
I'm drawing a filled shape using the UIBezierPath and i want to check if a user touches this shape. Here is my code:
- (void)drawRect:(CGRect)rect
{
aShape = [UIBezierPath bezierPathWithOvalInRect:
CGRectMake(0, 0, 200, 100)];
[[UIColor blackColor] setStroke];
[[UIColor redColor] setFill];
CGContextRef aRef = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(aRef, 50, 50);
aShape.lineWidth = 5;
[aShape fill];
[aShape stroke];
CGPoint x = CGPointMake(30, 40);
if([aShape containsPoint:x]) {
NSLog(@"in");
} else {
NSLog(@"out");
}
}
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
}
return self;
}
- (void)dealloc {
[aShape dealloc];
[super dealloc];
}
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *t = [[touches allObjects] objectAtIndex:0];
CGPoint p = [t locationInView:self];
[aShape containsPoint:p];
}
@end
I have some issues with the :containsPoint method. It is working in the drawRect-Code, but not in the touchesBegan method and I don't know why :( I would appreciate some help...Thx.
Upvotes: 0
Views: 1671
Reputation: 1007
For those having the same problem in Xamarin / MonoTouch, here is a similar solution:
public class FooControl : UIControl
{
private float _xOffset;
private float _yOffset;
private UIBezierPath _path;
public FooControl(RectangleF frame) : this(frame)
{
//offsets to move drawing origin to center of containing frame
_xOffset = Frame.Width / 2;
_yOffset = Frame.Height / 2;
}
public override void Draw(RectangleF rect)
{
base.Draw(rect);
using(CGContext g = UIGraphics.GetCurrentContext())
{
// move origin to middle of screen
g.TranslateCTM(_xOffset, _yOffset);
if (_path == null)
{
_path = new UIBezierPath();
//... build rest of path ...
_path.Close();
}
//... rest of drawing code goes here ...
}
}
public override UIView HitTest(PointF touchPoint, UIEvent uiEvent)
{
if (_path != null)
{
//important! to reverse original translation, use negative values
CGAffineTransform affine =
CGAffineTransform.MakeTranslation(-_xOffset, -_yOffset);
PointF localPoint = affine.TransformPoint(touchPoint);
if (_path.ContainsPoint(localPoint))
{
return this;
}
}
return null;
}
}
Upvotes: 0
Reputation: 28688
If I had to venture a guess, it isn't working as you expect in touchesBegan because you're not accounting for the fact that you drew the path offset. [aShape containsPoint:p]
isn't going to know about the context transform you applied previously.
On a slightly different note, [aShape dealloc]
you should never call dealloc on an object directly. The only time you call dealloc is on super at the end of your own dealloc. This line should be [aShape release]
Upvotes: 4