我有很多参展商的平面图。加载UIView
时,会显示UIImage
平面图,并检查数据库中是否有参展商及其位置列表。这些位置被加载到一个阵列中,并为每个参展商创建UIButton
,并将其放置在他们的展位所在的平面图上。点击时,此按钮将显示有关该参展商的信息。
以下是平面图的屏幕截图,其中包含用于呈现按钮的框。
这很好,因为它是我需要按钮是不规则的形状(三角形,五边形,圆形等)。因此,我需要一种绘制这些形状的方法,并按照按钮的方式单击它们。
我创建了一个测试类,它生成一个UIView
,其中包含形状并将其添加到原始UIView
。我觉得这可能不是正确的方法,因为我需要在屏幕上有许多按钮,这意味着许多视图堆叠在一起。我不知道如何检查哪个形状被点击,因为UIViews
会相互重叠。
可以在一个视图上绘制所有形状,然后添加视图吗?最好的办法是什么?
答案 0 :(得分:0)
在UI方面,最干净的事情是使用实际按钮。将其类型设置为自定义,并将其图像属性设置为要显示的图像。这样,按钮正确处理突出显示,并像常规按钮一样管理IBActions。您可以将所有按钮设置为指向相同的操作,并使用标记值来确定哪个按钮是哪个。
您可以通过代码或IB创建这些按钮 - 无论哪种更适合您的设计。
您也可以使用自定义视图或在其上绘制的单个视图执行此操作。如果您为每个展位使用视图,则需要为每个视图附加一个轻击手势识别器,并将其userInteractionEnabled标志设置为YES。
如果要对整个平面图使用绘图,则需要在绘图视图中添加点击手势识别器,然后解释点击的坐标以确定它所在的图像。
答案 1 :(得分:0)
倍率
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
地图代表视图的方法。因此,您将能够将当前触摸位置与所有形状进行比较,并计算接触点所处的形状。对于不同的形状有不同的方法(例如is point inside a rectangle?)
答案 2 :(得分:0)
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/
答案 3 :(得分:0)
最后这就是我所做的:
这种方法似乎比实际绘制数百个UIButton甚至CAS播放器更有效率,甚至在平面图上有300多个区域来检查整个过程是否即时。