gpt4 book ai didi

ios - UIBezierPath 中的 CGContextSaveGState 0x0

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:03:31 25 4
gpt4 key购买 nike

我正在尝试使用 Apple 的方法来检测一个点是否在 UIBezierPath 上。但是它会返回“无效上下文”。

正如您从 NSlog 中看到的那样,我正在传递一个 UIBezierPath 和一个要检查的点。在我的例子中是一个接触点。

我不明白为什么。有人可以向我解释一下或指出正确的方向吗?

NS日志-----

Path <UIBezierPath: 0x7f57110>
Contains point Path <UIBezierPath: 0x7f57110>
Touch point 425.000000 139.000000
<Error>: CGContextSaveGState: invalid context 0x0
<Error>: CGContextAddPath: invalid context 0x0
<Error>: CGContextPathContainsPoint: invalid context 0x0
<Error>: CGContextRestoreGState: invalid context 0x0
NO

直接来自有关如何确定路径中的点的 Apple 文档

- (BOOL)containsPoint:(CGPoint)point onPath:(UIBezierPath *)path inFillArea:(BOOL)inFill {

NSLog(@"contains point Path %@", path);
NSLog(@"Touch point %f %f", point.x, point.y );

CGContextRef context = UIGraphicsGetCurrentContext();
CGPathRef cgPath = path.CGPath;
BOOL isHit = NO;
// Determine the drawing mode to use. Default to detecting hits on the stroked portion of the path.
CGPathDrawingMode mode = kCGPathStroke;

if (inFill) { // Look for hits in the fill area of the path instead.
if (path.usesEvenOddFillRule)
mode = kCGPathEOFill;
else
mode = kCGPathFill;
}
// Save the graphics state so that the path can be removed later.
CGContextSaveGState(context);
CGContextAddPath(context, cgPath);

// Do the hit detection.
isHit = CGContextPathContainsPoint(context, point, mode);

CGContextRestoreGState(context);

return isHit;
}

这是我的 touchesBegan 方法。我的路径在 NSMutableArray 中。我解析数组以检查我的所有路径以查看是否有任何内容被触及。

- (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");
}

}
}

最佳答案

CGContextPathContainsPoint 方法需要图形上下文,Apple 的示例代码是从 UIGraphicsGetCurrentContext 中获取的。但是,UIGraphicsGetCurrentContext 仅在 -[UIView drawRect:] 内部或调用设置 UI 图形上下文的函数(如 UIGraphicsBeginImageContext)后起作用。

通过在描边副本上使用 CGPathCreateCopyByStrokingPath(在 iOS 5.0 中添加)和 CGPathContainsPoint,您可以在没有图形上下文的情况下执行 HitTest :

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");
}
}
}

请注意,CGPathCreateCopyByStrokingPath 可能有些昂贵,因此您可能希望对路径进行一次描边,并保存描边副本,而不是每次需要测试点时都对它们进行描边。

关于ios - UIBezierPath 中的 CGContextSaveGState 0x0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15348442/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com