UIBezierPath содержит Point не работает с touchSegan - PullRequest
0 голосов
/ 17 декабря 2010

Я рисую заполненную форму, используя 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

У меня есть некоторые проблемы с методом: includesPoint.Он работает в drawRect-Code, но не в методе touchesBegan, и я не знаю почему :( Буду признателен за некоторую помощь ... Спасибо.

Ответы [ 2 ]

4 голосов
/ 17 декабря 2010

Если бы мне пришлось рискнуть, то это не сработало так, как вы ожидаете от touchSegan, потому что вы не учитываете тот факт, что вы нарисовали смещение пути. [aShape containsPoint:p] не узнает о преобразовании контекста, которое вы применяли ранее.

На немного другой ноте [aShape dealloc] вы никогда не должны вызывать dealloc для объекта напрямую. Единственный раз, когда вы звоните в dealloc, это super в конце вашего собственного dealloc. Эта строка должна быть [aShape release]

0 голосов
/ 16 июля 2013

Для тех, у кого такая же проблема в 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;
    }
}
...