Ios UIBezierPath中的CGContextSaveGState 0x0
我试图使用苹果的方法来检测一个点是否在UIBezierPath上。但是,它返回一个“无效上下文” 正如您从NSlog中看到的,我正在传递一个UIBezierPath和一个要检查的点。就我而言,这是一个接触点 我不明白为什么。有人能给我解释一下或者给我指出正确的方向吗 NSLOG----- 这是我的触摸开始方法。我的路径在NSMutableArray中。我解析数组以检查所有路径,查看是否有任何路径被触碰。Ios UIBezierPath中的CGContextSaveGState 0x0,ios,objective-c,uitouch,uibezierpath,Ios,Objective C,Uitouch,Uibezierpath,我试图使用苹果的方法来检测一个点是否在UIBezierPath上。但是,它返回一个“无效上下文” 正如您从NSlog中看到的,我正在传递一个UIBezierPath和一个要检查的点。就我而言,这是一个接触点 我不明白为什么。有人能给我解释一下或者给我指出正确的方向吗 NSLOG----- 这是我的触摸开始方法。我的路径在NSMutableArray中。我解析数组以检查所有路径,查看是否有任何路径被触碰。 - (void)touchesBegan:(NSSet *)touches withEven
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint curPoint = [[touches anyObject] locationInView:self];
for (int i = 0; i < [pathInfo count]; i++){
NSArray *row = [[NSArray alloc] initWithArray:[pathInfo objectAtIndex:i]];
UIBezierPath *path = [row objectAtIndex:0];
NSLog(@"Path %@", path);
if ([self containsPoint:curPoint onPath:path inFillArea:NO]){
NSLog(@"YES");
} else {
NSLog(@"NO");
}
}
}
-(void)touchesbeated:(NSSet*)toucheevent:(UIEvent*)event{
CGPoint curPoint=[[触摸任何对象]位置查看:self];
对于(int i=0;i<[pathInfo计数];i++){
NSArray*行=[[NSArray alloc]initWithArray:[pathInfo objectAtIndex:i]];
UIBezierPath*path=[row objectAtIndex:0];
NSLog(@“路径%@”,路径);
if([self-containsPoint:curPoint-onPath:path-inFillArea:NO]){
NSLog(@“是”);
}否则{
NSLog(@“否”);
}
}
}
tl;dr:您应该使用CGPathContainsPoint(…)
出了什么问题 你的问题是,你没有背景,你试图得到它
CGContextRef context = UIGraphicsGetCurrentContext(); // <-- This line here...
编辑
如果要点击测试笔划路径,可以使用
CGPathCreateCopyByStrokingPath()
首先为正在笔划的路径创建一个新的填充路径(给定一定的宽度等)。OleBegeman已经介绍了如何做(包括一些示例代码) CGContextPathContainsPoint方法需要一个图形上下文,苹果的示例代码从UIGraphicsGetCurrentContext
获取。但是,UIGraphicsGetCurrentContext
仅在-[UIView drawRect:][/code>内部或在调用设置UI图形上下文的函数(如UIGraphicsBeginImageContext
)后起作用
通过在笔划副本上使用CGPathCreateCopyByStrokingPath
(在iOS 5.0中添加)和CGPathContainsPoint
,您可以在没有图形上下文的情况下执行命中测试:
static BOOL strokedPathContainsPoint(CGPathRef unstrokedPath,
const CGAffineTransform *transform, CGFloat lineWidth,
CGLineCap lineCap, CGLineJoin lineJoin, CGFloat miterLimit,
CGPoint point, bool eoFill)
{
CGPathRef strokedPath = CGPathCreateCopyByStrokingPath(unstrokedPath,
transform, lineWidth, lineCap, lineJoin, miterLimit);
BOOL doesContain = CGPathContainsPoint(strokedPath, NULL, point, eoFill);
CGPathRelease(strokedPath);
return doesContain;
}
您必须决定要使用的线宽和其他笔划参数。例如:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint curPoint = [[touches anyObject] locationInView:self];
for (int i = 0; i < [pathInfo count]; i++){
NSArray *row = [[NSArray alloc] initWithArray:[pathInfo objectAtIndex:i]];
UIBezierPath *path = [row objectAtIndex:0];
NSLog(@"Path %@", path);
if (strokedPathContainsPoint(path.CGPath, NULL, 10.0f, kCGLineCapRound,
kCGLineJoinRound, 0, curPoint, path.usesEvenOddFillRule))
{
NSLog(@"YES");
} else {
NSLog(@"NO");
}
}
}
-(void)touchesbeated:(NSSet*)toucheevent:(UIEvent*)event{
CGPoint curPoint=[[触摸任何对象]位置查看:self];
对于(int i=0;i<[pathInfo计数];i++){
NSArray*行=[[NSArray alloc]initWithArray:[pathInfo objectAtIndex:i]];
UIBezierPath*path=[row objectAtIndex:0];
NSLog(@“路径%@”,路径);
如果(strokedPathContainsPoint,path.CGPath,NULL,10.0f,kCGLineCapRound,
kCGLineJoinRound,0,curPoint,path.usesEvenOddFillRule)
{
NSLog(@“是”);
}否则{
NSLog(@“否”);
}
}
}
请注意,CGPathCreateCopyByStrokingPath
可能有点昂贵,因此您可能希望对路径进行一次笔划,并保存笔划副本,而不是每次需要测试点时都对其进行笔划。JasonBourne在调用CGContextPathContainsPoint
时使用的是kCGPathStroke
模式。CGPathContainsPoint
不采用模式参数,但有效地使用了kCGPathFill
或kcgpathOfill
,因此仅复制CGContextPathContainsPoint
的行为是不够的。我错过了关于绘图模式的第一部分这应该不会那么复杂。有没有一种简单的方法来确定路径是否在接触点的区域内,而无需我重新编写整个程序来补偿这一细节@罗布:哪一部分比较复杂?当你说“如果路径在接触点的区域内”,你是什么意思?如果想知道闭合路径是否包含点,可以使用CGPathContainsPoint
。但是如果你想知道一个点是否在路径附近,你需要精确地定义near,你需要有测试near的代码。我想我们已经为您提供了一种简单的方法,可以一起使用CGPathCreateCopyByStrokingPath
和CGPathContainsPoint
来定义和测试接近度。你为什么要重写整个程序?
BOOL isHit = CGPathContainsPoint(
path.CGPath,
NULL,
point,
path.usesEvenOddFillRule
);
static BOOL strokedPathContainsPoint(CGPathRef unstrokedPath,
const CGAffineTransform *transform, CGFloat lineWidth,
CGLineCap lineCap, CGLineJoin lineJoin, CGFloat miterLimit,
CGPoint point, bool eoFill)
{
CGPathRef strokedPath = CGPathCreateCopyByStrokingPath(unstrokedPath,
transform, lineWidth, lineCap, lineJoin, miterLimit);
BOOL doesContain = CGPathContainsPoint(strokedPath, NULL, point, eoFill);
CGPathRelease(strokedPath);
return doesContain;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint curPoint = [[touches anyObject] locationInView:self];
for (int i = 0; i < [pathInfo count]; i++){
NSArray *row = [[NSArray alloc] initWithArray:[pathInfo objectAtIndex:i]];
UIBezierPath *path = [row objectAtIndex:0];
NSLog(@"Path %@", path);
if (strokedPathContainsPoint(path.CGPath, NULL, 10.0f, kCGLineCapRound,
kCGLineJoinRound, 0, curPoint, path.usesEvenOddFillRule))
{
NSLog(@"YES");
} else {
NSLog(@"NO");
}
}
}