在我的应用程序中,我有一个要求,我需要用红色填充圆圈,百分比值为50%,80%是我从API获得的,如下图所示。
目前我使用以下代码来实现此目的。
let roundView = UIView(frame:CGRect(x: 100, y: 100, width: 250, height: 250))
roundView.backgroundColor = UIColor.white
roundView.layer.cornerRadius = roundView.frame.size.width / 2
// bezier path
let circlePath = UIBezierPath(arcCenter: CGPoint (x: roundView.frame.size.width / 2, y: roundView.frame.size.height / 2),
radius: roundView.frame.size.width / 2,
startAngle:CGFloat(M_PI_2),
endAngle: CGFloat (M_PI * 2.0),
clockwise: true)
circlePath.move(to: roundView.center)
// circle shape
let circleShape = CAShapeLayer()
circleShape.path = circlePath.cgPath
circleShape.strokeColor = UIColor.black.cgColor
circleShape.fillColor = UIColor.green.cgColor
circleShape.lineWidth = 1.5
// add sublayer
roundView.layer.addSublayer(circleShape)
// add subview
self.view.addSubview(roundView)*
显示如下
你能建议我怎么做。目前我正面临将问题转换为度数的问题。
答案 0 :(得分:14)
你的问题是你没有画出完整的路径 - 单独一个弧就不会这样做。您需要在中心开始路径,并绘制线段的直边和弧。这是在Playground中 - 我尽量保持你的风格,但引入了参数proportion
这是你的百分比,startAngle
这是片段的方向。
import UIKit
let roundView = UIView(frame:CGRect(x: 100, y: 100, width: 250, height: 250))
roundView.backgroundColor = UIColor.white
roundView.layer.cornerRadius = roundView.frame.size.width / 2
// vary this to move the start of the arc
let startAngle = -CGFloat.pi / 2 // This corresponds to 12 0'clock
// vary this to vary the size of the segment, in per cent
let proportion = CGFloat(80)
let centre = CGPoint (x: roundView.frame.size.width / 2, y: roundView.frame.size.height / 2)
let radius = roundView.frame.size.width / 2
let arc = CGFloat.pi * 2 * proportion / 100 // i.e. the proportion of a full circle
// Start a mutable path
let cPath = UIBezierPath()
// Move to the centre
cPath.move(to: centre)
// Draw a line to the circumference
cPath.addLine(to: CGPoint(x: centre.x + radius * cos(startAngle), y: centre.y + radius * sin(startAngle)))
// NOW draw the arc
cPath.addArc(withCenter: centre, radius: radius, startAngle: startAngle, endAngle: arc + startAngle, clockwise: true)
// Line back to the centre, where we started (or the stroke doesn't work, though the fill does)
cPath.addLine(to: CGPoint(x: centre.x, y: centre.y))
// n.b. as @MartinR points out `cPath.close()` does the same!
// circle shape
let circleShape = CAShapeLayer()
circleShape.path = cPath.cgPath
circleShape.strokeColor = UIColor.black.cgColor
circleShape.fillColor = UIColor.green.cgColor
circleShape.lineWidth = 1.5
// add sublayer
roundView.layer.addSublayer(circleShape)
roundView
加分 - 添加文字标签
在我的初步答案之后,OP抛出了几个弯曲的球,包括定位片段(在上面实现)并用百分比标记片段,真的应该是一个单独的问题,但是,想要在饼图上做这不是一件不合理的事情,所以这就是...
// Bonus - add text layer
// choose your font
let fontSize = CGFloat(20)
let font = UIFont.systemFont(ofSize: fontSize)
let attributes = [NSFontAttributeName: font]
// Format the string
let str = String(format: "%3.0f%%", proportion)
// Calculate the text size
let textSize = str.size(attributes: attributes)
// Assume the centre of the text is half way along the bisector of the segment
let halfAngle = startAngle + arc / 2
let centreText = CGPoint(x: centre.x + radius * cos(halfAngle) / 2, y: centre.y + radius * sin(halfAngle) / 2)
// calculate the the lower left of the label given the size
let originText = CGPoint(x: centreText.x - textSize.width / 2, y: centreText.y - textSize.height / 2)
// Allocate the text layer
let label = CATextLayer()
label.font = font
label.fontSize = fontSize
label.frame = CGRect(origin: originText, size: textSize)
label.string = str
label.alignmentMode = kCAAlignmentCenter
label.foregroundColor = UIColor.black.cgColor
roundView.layer.addSublayer(label)
roundView