问题描述
我有一些 UIView 子类,我在 drawRect 中绘制了 UIBezierPaths.在添加这些视图的 viewController 中,我需要进行命中测试以查看是否在贝塞尔曲线路径内发生了点击.我尝试在视图子类中创建一个 UIBezierPath 变量,然后对其进行测试.但当然,偏移量是完全错误的 - 我会在屏幕的顶角而不是形状上得到点击.
I have some UIView subclasses where I draw UIBezierPaths in drawRect. In the viewController that adds these views, I need to do a hit test to see if a tap happened inside the bezier path. I tried creating a UIBezierPath variable in the view subclass, then testing against that. But of course, the offset was completely wrong - I would get hits in the top corner of the screen, rather than over the shape.
谁能建议最好的方法来做到这一点?这是否有意义,还是我应该添加一些代码?
Can anyone suggest the best way to do this? Does this make sense, or should I add some code?
谢谢,詹姆斯
推荐答案
这是我的自定义三角形视图.它比贝塞尔路径简单得多,但我相信它应该大致相同.我还有一个类别,它基于 alpha 级别以像素为单位进行测试,我将其用于带有 alpha 层的 UIImages.(在这篇文章中检索 UIImage 的像素 alpha 值)
This is a custom triangle view I have. Its much simpler than a bezier path but I believe it should work about the same. I also have a category that hittests based on alpha level on a pixel-per-pixel basis that I use for UIImages with alpha layers. (Its in this post Retrieving a pixel alpha value for a UIImage)
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextMoveToPoint(context, 0.0, 0.0);
CGContextAddLineToPoint(context, rect.size.width, 0.0);
CGContextAddLineToPoint(context, 0.0, rect.size.height);
CGContextClosePath(context);
CGContextSetFillColorWithColor(context, triangleColor.CGColor);
CGContextFillPath(context);
CGContextSaveGState(context);
[self.layer setShouldRasterize:YES];
[self.layer setRasterizationScale:[UIScreen mainScreen].scale];
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
CGMutablePathRef trianglePath = CGPathCreateMutable();
CGPathMoveToPoint(trianglePath, NULL, 0.0, 0.0);
CGPathAddLineToPoint(trianglePath, NULL, self.frame.size.width, 0.0);
CGPathAddLineToPoint(trianglePath, NULL, 0.0, self.frame.size.height);
CGPathCloseSubpath(trianglePath);
if (CGPathContainsPoint(trianglePath, nil, point, YES)) {
CGPathRelease(trianglePath);
return self;
} else {
CGPathRelease(trianglePath);
return nil;
}
}
这篇关于命中测试 UIView 子类的填充区域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!