UIBezierPath containsPoint不使用touchesBegan

时间:2010-12-17 15:01:07

标签: objective-c cocoa-touch uikit core-graphics

我正在使用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。

2 个答案:

答案 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;
    }
}