我正在使用UIBezierPath绘制填充形状,我想检查用户是否触摸此形状。这是我的代码:
- (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
我遇到了一些问题:containsPoint方法。它在drawRect-Code中工作,但不是在touchesBegan方法中,我不知道为什么:(我很感激一些帮助... Thx。
答案 0 :(得分:4)
如果我不得不猜测,它在touchesBegan中没有像你期望的那样工作,因为你没有考虑你绘制路径偏移的事实。 [aShape containsPoint:p]
无法了解您之前应用的上下文转换。
稍微不同的是,[aShape dealloc]
你永远不应该直接在对象上调用dealloc。你调用dealloc的唯一一次是在你自己的dealloc结束时超级。此行应为[aShape release]
答案 1 :(得分:0)
对于那些在Xamarin / MonoTouch中遇到同样问题的人来说,这是一个类似的解决方案:
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;
}
}