【问题标题】:How to draw slices in semicircle shape layers in objective-c如何在objective-c中以半圆形图层绘制切片
【发布时间】:2018-12-25 23:16:40
【问题描述】:

我使用以下代码绘制了半圆形

- (void)drawRect:(CGRect)rect
{
    UIBezierPath *bezierPath = [UIBezierPath bezierPath];
    [bezierPath addArcWithCenter:CGPointMake(self.frame.size.width, self.frame.size.height/2) radius:150 startAngle:0 endAngle:2 * M_PI clockwise:YES];
     CAShapeLayer *progressLayer = [[CAShapeLayer alloc] init];
    [progressLayer setPath:bezierPath.CGPath];
    [progressLayer setStrokeColor:[UIColor colorWithWhite:1. alpha:.2].CGColor];
    [progressLayer setFillColor:[UIColor colorWithRed:67.0/255.0 green:144.0/255.0 blue:246.0/255.0 alpha:1.0].CGColor];
    [progressLayer setLineWidth:.7 * self.bounds.size.width];
    [[self layer] addSublayer:progressLayer];
      // [self drawWheel];
  }

我想使用objective-c在半圆中绘制一个像饼图一样的切片,它应该完全匹配如下所示的图像

谁能给我建议解决办法

【问题讨论】:

  • 我会怎么做?使用一张纸和一支笔。隔离每个点,尝试了解如何获取其位置,尝试了解如何从一个点到下一个点(是一条线,是一条弧吗?如果是,中心是什么,半径是什么,总角度)?等等,因为它只是关于数学/逻辑,而且做起来很“长”(所以有点太宽泛了)。请注意,您的图像有一点“更难”(另一个小困难),即小圆圈与大圆圈的中心不同。
  • 我猜这是一个弧线(即饼图是可点击的)。我实际上遵循了教程raywenderlich.com/9864/…。但我发现很难让圆的中点画出圆弧。

标签: ios objective-c cocoa-touch core-animation cashapelayer


【解决方案1】:

将此代码添加到您的drawRect(_:)

let radius = min(bounds.size.width, bounds.size.height) / 2;
let center = CGPoint.init(x: bounds.size.width / 2, y: bounds.size.height / 2)
let sliceCount = 6;

let slicePath = UIBezierPath.init()
slicePath.lineWidth = 1;
slicePath.move(to: center)

var angle: CGFloat = 0 - (CGFloat.pi / 2);
var interval: CGFloat = (CGFloat.pi) / CGFloat(sliceCount)



for i in 0 ... sliceCount {
    let x = center.x + (radius * cos(angle))
    let y = center.y + (radius * sin(angle))
    slicePath.addLine(to: CGPoint.init(x: x, y: y))
    slicePath.move(to: center)
    angle -= interval;
}

UIColor.white.setStroke()
slicePath.stroke()

这是结果。

更新 另一个与您的目标非常相似的代码

override func draw(_ rect: CGRect) {

    let radius = min(bounds.size.width, bounds.size.height) / 2;
    let center = CGPoint.init(x: bounds.size.width, y: bounds.size.height / 2)
    let sliceCount = 6;

    let semiCirclePath = UIBezierPath.init()
    semiCirclePath.move(to: center)
    semiCirclePath.addArc(withCenter: center, radius: radius, startAngle: CGFloat.pi / 2, endAngle: CGFloat.pi + (CGFloat.pi / 2) , clockwise: true)
    semiCirclePath.close()
    UIColor.blue.setFill()
    semiCirclePath.fill()



    let slicePath = UIBezierPath.init()
    slicePath.lineWidth = 1;
    slicePath.move(to: center)

    var angle: CGFloat = 0 - (CGFloat.pi / 2);
    var interval: CGFloat = (CGFloat.pi) / CGFloat(sliceCount)



    for i in 0 ... sliceCount {
        let x = center.x + (radius * cos(angle))
        let y = center.y + (radius * sin(angle))
        slicePath.addLine(to: CGPoint.init(x: x, y: y))
        slicePath.move(to: center)
        angle -= interval;
    }

    UIColor.white.setStroke()
    slicePath.stroke()

    semiCirclePath.removeAllPoints()
    semiCirclePath.move(to: center)
    semiCirclePath.addArc(withCenter: center, radius: 30, startAngle: CGFloat.pi / 2, endAngle: CGFloat.pi + (CGFloat.pi / 2) , clockwise: true)
    UIColor.lightGray.setFill()
    semiCirclePath.fill()
}

这是它的样子,

第二次更新 对于一个完全看起来像的人

override func draw(_ rect: CGRect) {

    let radius = min(bounds.size.width, bounds.size.height) / 2;
    let center = CGPoint.init(x: bounds.size.width, y: bounds.size.height / 2)
    let selectedSliceIndex = 2;
    let sliceCount = 6;

    let slicePath = UIBezierPath.init()
    let selectedSlicePath = UIBezierPath.init()
    slicePath.lineWidth = 1;
    slicePath.move(to: center)

    var angle: CGFloat = 0 - (CGFloat.pi / 2);
    let interval: CGFloat = (CGFloat.pi) / CGFloat(sliceCount)

    for i in 0 ... sliceCount {
        let x = center.x + (radius * cos(angle))
        let y = center.y + (radius * sin(angle))
        slicePath.addLine(to: CGPoint.init(x: x, y: y))
        slicePath.move(to: center)


        if i == selectedSliceIndex {
            selectedSlicePath.move(to: center)
            selectedSlicePath.addArc(withCenter: center, radius: radius, startAngle: angle - interval, endAngle: angle, clockwise: true)
            selectedSlicePath.close()
        }

        angle -= interval;
    }

    // outer blue circle
    let semiCirclePath = UIBezierPath.init()
    semiCirclePath.move(to: center)
    semiCirclePath.addArc(withCenter: center, radius: radius, startAngle: CGFloat.pi / 2, endAngle: CGFloat.pi + (CGFloat.pi / 2) , clockwise: true)
    semiCirclePath.close()
    UIColor.blue.setFill()
    semiCirclePath.fill()

    // lines
    UIColor.white.setStroke()
    slicePath.stroke()

    // selected slice
    UIColor.lightGray.setFill()
    selectedSlicePath.fill()
    UIColor.clear.setFill()

    // inner gray circle
    semiCirclePath.removeAllPoints()
    semiCirclePath.move(to: center)
    semiCirclePath.addArc(withCenter: center, radius: 30, startAngle: CGFloat.pi / 2, endAngle: CGFloat.pi + (CGFloat.pi / 2) , clockwise: true)
    UIColor.lightGray.setFill()
    semiCirclePath.fill()

}

您可能需要调整一些值才能看起来漂亮。

我在 ViewController 中移动了视图的框架,仅供参考。

【讨论】:

  • 太棒了。太棒了...它的工作谢谢。实际上我是在 Objective-c 中做的,并将其转换为 Objective-c
  • 我可以使用 CATextlayer 添加文本吗?
  • @sathyarakesh 我没有尝试过使用 CATextLayer 而是使用 UILabel 的那种 UI。只需在 [CATextLayer] 或 [UILabel] 上使用 Trig 函数和 CGAffineTransform 并正确布局。它应该工作正常。
  • @sathyarakesh 请分享objective-c代码,我需要在同一个半圆上切片和操作项目
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-04
  • 1970-01-01
相关资源
最近更新 更多