如何在圆形视图内检测触摸

3

输入图像描述

我有一个圆形的UIView。我必须只在紫色圆圈内检测触摸。所有在圆外的触摸,例如黑色正方形和白色背景,必须被忽略。

设置半径并检测触摸将没有任何用处,因为当多个视图重叠在一起并且具有不同的控制器时,管理将变得困难。

是否有办法解决这个问题?请给我一些建议。


你有紫色圆形的框架吗? - Manu
这不是完全重复,但上面问题的答案很可能可以解决这个问题。 - Taryn East
4个回答

6
创建一个名为 CircularView 的自定义子类,并覆盖 pointInside:withEvent: 方法,以忽略位于圆形外部的点。这个子类的对象将是自包含的,你可以按照自己的想法进行排列。
要确定一个圆形区域是否包含一个点,可以利用 Core Graphics 函数 CGPathContainsPointUIBezierPath 中的 containsPoint: 方法。这将需要你记住表示圆形的 CGPathRefUIBezierPath 对象。在这个例子中,我假设你使用 UIBezierPath 创建了一个圆形路径,并将其存储为 CircularView 类的属性。
@interface CircularView : UIView

// initialize this when appropriate
@propery (nonatomic, strong) UIBezierPath *circularPath;

@end

@implementation CircularView

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    return [circularPath containsPoint:point];
}

@end

就是这样。


我尝试使用圆形创建贝塞尔路径,但是我无法将背景设置为透明颜色。它总是显示为黑色。有没有办法可以使背景颜色透明,这样当我将视图叠加在一起时,角落不会重叠。 - barryjones
CircularView 类中的背景设置为 clearColor - Anurag
这是我看到的- http://i46.tinypic.com/1j9st1.png。有三个CircularView对象重叠在一起。 - Anurag

4

如果您有圆的半径,可以轻松应用条件来触摸。检查触摸点与圆心之间的距离,检查距离是否小于圆的半径,然后处理触摸,否则忽略它。

您可以使用以下方法计算距离:

-(float)distanceWithCenter:(CGPoint)current with:(CGPoint)SCCenter
{
    CGFloat dx=current.x-SCCenter.x;
    CGFloat dy=current.y-SCCenter.y;

    return sqrt(dx*dx + dy*dy);
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
 CGFloat radius=5;
 CGPoint centerOfCircle=CGPointMake(140,200);
 UITouch *touch=[touches anyObject];
 CGPoint touchPoint=[touch locationInView:self.view];

 CGFloat distance=[self distanceWithCenter:centerOfCircle with:touchPoint];

 if (distance<=radius) {
  //perform your tast.
 }
}

我要补充的是,与其计算排序,不如将平方和与圆的半径的平方进行比较。 - Christopher Schardt

2
创建一个UIView的子类用于你的圆,然后像这样覆盖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' 变量,但这种方式更容易测试。

-2
你可以简单地创建一个按钮,设置它的自定义大小并使其成为圆形,每当用户触摸它时,它可以将1添加到整数或浮点型的触摸次数。就这么简单。

那对我来说行不通,因为我需要在其中显示文本和其他值。而且我还会在其下面添加更多的大圆。基本上是一个轮子里面的轮子。我只想忽略在角落处的触摸。 - barryjones

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接