[英]Adding multiple tappable shapes to UIView
我有很多展位的平面图。 加载UIView
时,将显示UIImage
和平面图,并检查数据库以获取参展商及其位置的列表。 将位置加载到阵列中,并为每个参展商创建一个UIButton
,并将其放置在其展位所在的平面图上。 点击时,此按钮将显示有关该参展商的信息。
这是平面图的屏幕截图,其中带有渲染按钮的框。
这很好用,但是我需要将按钮设置为不规则形状(三角形,五边形,圆形等)。 因此,我需要一种绘制这些形状并使其与按钮一样可单击的方法。
我创建了一个测试类,该类生成一个包含形状的UIView
并将其添加到我的原始UIView
。 我感觉这可能不是正确的方法,因为我将需要在屏幕上具有许多按钮,这意味着许多视图相互堆叠。 我不知道如何检查点击的形状,因为UIViews
会相互重叠。
是否可以在一个视图上绘制所有形状,然后添加视图? 最好的方法是什么?
就UI而言,最干净的方法是使用实际的按钮。 将其类型设置为custom,并将其image属性设置为要显示的图像。 这样,按钮可以正确处理突出显示,并像常规按钮一样管理IBAction。 您可以将所有按钮设置为指向相同的动作,并使用标签值确定哪个按钮是哪个按钮。
您可以从代码中或在IB中创建这些按钮-更好地适合您的设计。
您也可以使用自定义视图或上面带有图形的单个视图来执行此操作。 如果对每个展位使用视图,则需要在每个视图上附加一个轻击手势识别器,并将其userInteractionEnabled标志设置为YES。
如果要在整个平面图中使用图形,则需要在图形视图中添加一个轻击手势识别器,然后解释该轻敲的坐标以找出其所放到的图像。
覆盖- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
地图表示者视图的- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
方法的- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
方法。 因此,您将能够将当前触摸位置与所有形状进行比较,并计算出您的触摸点所处的形状。 对于不同的形状有不同的方法(例如,点在矩形内吗? )
ole有一个很棒的项目: OBShapedButtons 。 他通过检查触摸像素的alpha值并覆盖-pointInside:withEvent:
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
// Return NO if even super returns NO (i.e., if point lies outside our bounds)
BOOL superResult = [super pointInside:point withEvent:event];
if (!superResult) {
return superResult;
}
// Don't check again if we just queried the same point
// (because pointInside:withEvent: gets often called multiple times)
if (CGPointEqualToPoint(point, self.previousTouchPoint)) {
return self.previousTouchHitTestResponse;
} else {
self.previousTouchPoint = point;
}
BOOL response = NO;
if (self.buttonImage == nil && self.buttonBackground == nil) {
response = YES;
}
else if (self.buttonImage != nil && self.buttonBackground == nil) {
response = [self isAlphaVisibleAtPoint:point forImage:self.buttonImage];
}
else if (self.buttonImage == nil && self.buttonBackground != nil) {
response = [self isAlphaVisibleAtPoint:point forImage:self.buttonBackground];
}
else {
if ([self isAlphaVisibleAtPoint:point forImage:self.buttonImage]) {
response = YES;
} else {
response = [self isAlphaVisibleAtPoint:point forImage:self.buttonBackground];
}
}
self.previousTouchHitTestResponse = response;
return response;
}
另一个测试该点是否在图层蒙版中的示例代码,也许您可以更轻松地进行调整:
@implementation MyView
//
// ...
//
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
CGPoint p = [self convertPoint:point toView:[self superview]];
if(self.layer.mask){
if (CGPathContainsPoint([(CAShapeLayer *)self.layer.mask path], NULL, p, YES) )
return YES;
}else {
if(CGRectContainsPoint(self.layer.frame, p))
return YES;
}
return NO;
}
@end
全文: http : //blog.vikingosegundo.de/2013/10/01/hittesting-done-right/
最后,这就是我所做的:
这种方法似乎比实际绘制数百个UIButton甚至CAShaplayers,甚至在平面图上具有300多个区域来检查整个过程是否立即显示都更为有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.