UIBezierPath containsPoint: don't work correctly?(Updated: touch location in superview how to handle?)

帅比萌擦擦* 提交于 2021-02-08 05:46:40

问题


So I have 2 UIViews witch can draw a bezierpath and then returns the path. Then I need to check if the path contains a point I do this with help of [path containsPoint:currentObject.position]and it works for one of the views but not the other. One view is on the top half of the iPhone and the other view is on the bottom half. The one on the bottom don't work. I tried to switch the views, and then it was the same problem, the bottom one doesn't work.

Here is some code:

in mainviewcontroller:

-(void)didEndPath:(UIBezierPath *)path DrawView:(DrawView *)draw {
    if ([path containsPoint:currentObject.position]) {
        //do stuff
    }
}

and in drawview touches ended I do this:

[self.delegate didEndPath:currentPath DrawView:self];

Why doesn't it work, can it be that the view has another origin then self.view? How do I fix it?

EDIT:

Okey, so I found the problem but not the solution.

If I change the touch methods in my UIView from this: startPoint = [touch locationInView:self];to this startPoint = [touch locationInView:self.superview];then it reads the touches correctly but my path won't draw. Still the problem is only with the bottom uiview. So how can I change so it returns a path with touches location in superview, but draws it within it self?


回答1:


I solved the problem by making 2 paths. One with points from superview and one without. It works but i don't know if its the best solution.




回答2:


Check out the documentation:

A point is not considered to be enclosed by the path if it is inside an open subpath,   
regardless of whether that area would be painted during a fill operation. Therefore, to
determine mouse hits on open paths, you must create a copy of the path object and  
explicitly close any subpaths (using the closePath method) before calling this method.

My guess is that you left a subpath opened, so containsPoint returns NO.




回答3:


You should be able to just convert the points between the views like this

CGPoint locationInSuperView = [self convertPoint:point toView:self.superview];



回答4:


I had a similar problem, where containsPoint: always returned NO

I ended up making my own method which checks if the CGPoint is within the bounds of the UIBezierPath

- (BOOL)bezierPath:(UIBezierPath*)bezierPath containsPoint:(CGPoint)point
{
    CGRect bezierRect = bezierPath.bounds;

    if( bezierRect.origin.x < point.x && bezierRect.origin.x + bezierRect.size.width > point.x &&
       bezierRect.origin.y < point.y && bezierRect.origin.y + bezierRect.size.height > point.y ){
        return YES;
    }
    return NO;
}

Side note: you could also make this into a category method, I had no need for that.



来源:https://stackoverflow.com/questions/13787971/uibezierpath-containspoint-dont-work-correctlyupdated-touch-location-in-sup

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!