【问题标题】:Circle button on iOSiOS 上的圆形按钮
【发布时间】:2012-03-26 12:04:15
【问题描述】:

是否可以创建如下图所示的两个按钮?看起来您应该使用 UIButton 或 UIImageView 但如果我单击区域 1,它仍然充当单击按钮 1。当我单击区域 1 时也应该触发按钮 2!

【问题讨论】:

  • 除非您需要两个操作,否则为什么不将它们作为单个图像封装在一个不可见的按钮中?

标签: iphone objective-c ios button geometry


【解决方案1】:

如果上述响应不可接受,您可以实现 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;
}

【讨论】:

    【解决方案2】:

    您可以通过切割图层并设置按钮的半径来制作圆形按钮。

    [[按钮层] setCornerRadius:8.0f];

    您也可以尝试更改半径。

    【讨论】:

    • 设置cornerRadius只影响图片,area1在顶部按钮还是可以点击的
    【解决方案3】:

    是的,当然可以。

    您可以通过 IB 将单个操作与多个选择器连接起来。
    也可以在 button1 触发的方法内部直接调用 button2 触发的方法。

    【讨论】:

      【解决方案4】:

      这很棘手,但有可能: 您只能使用一个按钮,但在事件 touchUpInside 之后进行一些验证。您应该计算此触摸点是否在“button1”的圆圈内。对于这个任务,你需要有一些数学知识 - How do I calculate a point on a circle’s circumference?

      【讨论】:

        【解决方案5】:

        将较小的 Button 1 的 userInteractionEnabled 设置为 NO。所有事件都将转到较大的 Button 2。

        【讨论】:

          【解决方案6】:

          为此,我创建了两个圆形矩形按钮,一个长而细,另一个更宽。他们一起构建了一个像胖乎乎的加号的形状,非常接近一个圆形,考虑到苹果接受 44 px 作为最小可舒适按压尺寸。如果要更改图像,请将另一个图像设置为其 imageView 以突出显示状态,并连接两个按钮的多个操作(如果要在图像视图上模仿按钮突出显示状态,则触摸不够)。或者,您可以添加观察者并根据按钮更改图像视图的突出显示状态

          【讨论】:

            【解决方案7】:

            在圆形按钮上处理 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”变量,但这种方式更容易测试。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2013-10-09
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-06-21
              • 2012-08-28
              相关资源
              最近更新 更多