标签曲线段

时间:2014-03-19 21:32:25

标签: ios objective-c geometry computational-geometry

我想标记以下曲线的每个部分,如图所示。标签原点应从曲线段的中间开始,参见图形。我认为我的逻辑中的某些东西并不完全正确。你可以帮助我的代码中的错误在哪里?我认为代码和图解释了自己。

感谢您的时间和帮助!

    CGFloat radius = self.height / 3.2f; // radius of the curve
    CGPoint center = CGPointMake(self.width / 2.f, self.height / 2.f); //center of the curve
    UIBezierPath* circlePath = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:degreesToRadian(270.f) endAngle:DEGREES_TO_RADIANS(269.999f) clockwise:YES]; // go around like the clock

    CGFloat strokeStart = 0.f;
    // Add the parts of the curve to the view
    for (int i = 0; i < segmentValues.count; i++) {
        NSNumber *value = [segmentValues objectAtIndex:i];
        CGFloat strokeEnd = [value floatValue] / kPercentHundred;

        CAShapeLayer *circle = [CAShapeLayer layer];
        circle.path          = circlePath.CGPath;
        circle.lineCap       = kCALineCapButt;
        circle.fillColor     = [UIColor clearColor].CGColor;
        circle.strokeColor   = [[colors objectAtIndex:i] CGColor];
        circle.lineWidth     = kWidhtLine;
        circle.zPosition     = 1.f;
        circle.strokeStart   = strokeStart;
        circle.strokeEnd     = strokeStart + strokeEnd;
        [self.layer addSublayer:circle];

        UIView *example = [[UIView alloc] init];
        example.backgroundColor = kColorRed;
        example.size = CGSizeMake(10, 10);
        // middle = "(circle.strokeStart + circle.strokeEnd) / 2.f"
        // * convert percent to degree
        CGFloat angle = (circle.strokeStart + circle.strokeEnd) / 2.f * 360.f;
        // determine the point and add the right offset
        example.origin = CGPointMake(cosf(angle) * radius + center.x, sinf(angle) * radius + center.y);
        [self addSubview:example];

        strokeStart = circle.strokeEnd;
    }

我得到了什么。 What I got

我对概念的期望与下图类似。

enter image description here

3 个答案:

答案 0 :(得分:1)

我不确定你的目标是什么。你说你想创建标签,但你在代码中创建的是通用的UIView对象。

然后你在视图上设置属性“origin”,但据我所知,UIView没有原点。它有一个框架,它有一个原始组件,但不是一个原始属性。我猜你发布的代码不是实际的,运行代码。

您希望标签位于圆圈的中心吗?如果是这样,您应该将文本对齐设置为NSTextAlignmentCenter,并设置视图的center属性而不是frame.origin。

我在github上有一个工作示例项目,它创建一个模拟时钟并在其周围放置标签。您可以查看代码以了解如何执行此操作:

Analog clock sample project

(该项目还展示了如何使用新的弹簧物理UIView动画方法。)

答案 1 :(得分:1)

有两个关键问题:

  1. 您可以通过以下方式计算角度:

    CGFloat angle = (circle.strokeStart + circle.strokeEnd) / 2.f * 360.f;
    

    然后,您继续将其用于cossin函数。但是,那些期望弧度值,因此在将这些值用于这些函数之前,必须将其转换为弧度。因此,产生:

    CGFloat angle = degreesToRadian((circle.strokeStart + circle.strokeEnd) / 2.f * 360.f);
    

    (顺便说一句,我不知道你喜欢degreesToRadian还是DEGREES_TO_RADIANS,但你应该使用其中一种。)

    或者,更简单地说,您可以直接转换为弧度:

    CGFloat angle = (circle.strokeStart + circle.strokeEnd) / 2.f * M_PI * 2.0;
    
  2. 你已经将圆圈旋转了90度(可能是因为它会开始一个&#34; 12 o&#39;时钟&#34;而不是&#34; 3 o&#39;时钟&#34;) 。好吧,如果你旋转圆圈,那么当你计算angle视图的位置时,你必须旋转example

    example.center = CGPointMake(cosf(angle - M_PI_2) * radius + center.x, sinf(angle - M_PI_2) * radius + center.y);
    
  3. 这会产生:

    enter image description here

答案 2 :(得分:-1)

嗯,我对我来说有点晚了;)

我认为你必须使用UIView :: setCenter这将解决你的问题。那么视图的中心就在你的圆圈上。

编辑:操纵位置更容易。