【发布时间】:2012-03-26 12:04:15
【问题描述】:
是否可以创建如下图所示的两个按钮?看起来您应该使用 UIButton 或 UIImageView 但如果我单击区域 1,它仍然充当单击按钮 1。当我单击区域 1 时也应该触发按钮 2!
【问题讨论】:
-
除非您需要两个操作,否则为什么不将它们作为单个图像封装在一个不可见的按钮中?
标签: iphone objective-c ios button geometry
是否可以创建如下图所示的两个按钮?看起来您应该使用 UIButton 或 UIImageView 但如果我单击区域 1,它仍然充当单击按钮 1。当我单击区域 1 时也应该触发按钮 2!
【问题讨论】:
标签: iphone objective-c ios button geometry
如果上述响应不可接受,您可以实现 UIButton 的自定义子类,覆盖 pointInside:withEvent:。
假设您的视图完全是正方形,而图形完全是圆形并填充了整个正方形,一个示例可能是:
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
// check that the point is at least inside the normal rect
if(![super pointInside:point withEvent:event]) return NO;
// we'll assume a square view with an exact circle inside, so
// the radius of the circle is just half the width
CGFloat radius = self.bounds.size.width*0.5f;
// the point (radius, radius) is also the centre of the view, so...
CGFloat squareOfDistanceFromCentre =
(radius - point.x)*(radius - point.x) +
(radius - point.y)*(radius - point.y);
// if the point is too far away, return NO
if(squareOfDistanceFromCentre > radius*radius) return NO;
// otherwise we've exhausted possible reasons for answering NO
return YES;
}
【讨论】:
您可以通过切割图层并设置按钮的半径来制作圆形按钮。
[[按钮层] setCornerRadius:8.0f];
您也可以尝试更改半径。
【讨论】:
是的,当然可以。
您可以通过 IB 将单个操作与多个选择器连接起来。
也可以在 button1 触发的方法内部直接调用 button2 触发的方法。
【讨论】:
这很棘手,但有可能: 您只能使用一个按钮,但在事件 touchUpInside 之后进行一些验证。您应该计算此触摸点是否在“button1”的圆圈内。对于这个任务,你需要有一些数学知识 - How do I calculate a point on a circle’s circumference?
【讨论】:
将较小的 Button 1 的 userInteractionEnabled 设置为 NO。所有事件都将转到较大的 Button 2。
【讨论】:
为此,我创建了两个圆形矩形按钮,一个长而细,另一个更宽。他们一起构建了一个像胖乎乎的加号的形状,非常接近一个圆形,考虑到苹果接受 44 px 作为最小可舒适按压尺寸。如果要更改图像,请将另一个图像设置为其 imageView 以突出显示状态,并连接两个按钮的多个操作(如果要在图像视图上模仿按钮突出显示状态,则触摸不够)。或者,您可以添加观察者并根据按钮更改图像视图的突出显示状态
【讨论】:
在圆形按钮上处理 pointInside 的一种简洁方法是:
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
if (![super pointInside:point withEvent:event])
{
return NO;
}
BOOL isInside = (pow((point.x-self.frame.size.width/2), 2) + pow((point.y - self.frame.size.height/2), 2) < pow((self.frame.size.width/2), 2)) ? YES:NO;
return isInside;
}
您可以放弃“isInside”变量,但这种方式更容易测试。
【讨论】: