问题描述
override func draw(_ rect: CGRect) {
super.draw(rect)
if let context = UIGraphicsGetCurrentContext()
{
let width = fmin(self.frame.size.width,self.frame.size.height)
let offset_x = abs(width - self.frame.size.width)/2
let offset_y = abs(width - self.frame.size.height)/2
let padding = CGFloat(0.5)
let radius_size = (width/2) - (padding*2)
let circle_width = radius_size/4
context.setstrokeColor(UIColor.black.cgColor)
// Draw a circle
for i in 0 ..< 4
{
let offset = CGFloat(i) * circle_width
context.strokeEllipse(in:
CGRect(
x: padding + offset + offset_x,y: padding + offset + offset_y,width: (radius_size - offset)*2,height: (radius_size - offset)*2))
}
let angles: [CGFloat] = [87.0,112.0,150]
let angles2: [CGFloat] = [210.0,250.0,330.0]
let center = CGPoint(x: width/2 + offset_x,y: width/2 + offset_y)
for angle in angles {
drawLine(context: context,center: center,radius: radius_size,angle: angle)
}
for angle in angles2 {
drawLine(context: context,radius: radius_size * 3 / 4,angle: angle)
}
context.strokePath()
}
}
func drawLine(context: CGContext,center: CGPoint,radius: CGFloat,angle: CGFloat) {
context.move(to: center)
context.addLine(to: CGPoint(x: center.x + radius * cos(angle * .pi / 180),y: center.y - radius * sin(angle * .pi / 180)))
}
我希望能够在UILabels之间创建居中位置,并旋转到正确的角度,我在照片编辑器中创建了一个示例:
谢谢。
解决方法
我找到了答案:
func drawCurvedText(angle: CGFloat,text: String) {
drawCurvedString(
on: textView.layer,text: NSAttributedString(
string: text,attributes: [
NSAttributedString.Key.foregroundColor: UIColor.white,NSAttributedString.Key.font: UIFont.systemFont(ofSize: 15)
]),angle: -angle,radius: 130)
}
func drawCurvedString(on layer: CALayer,text: NSAttributedString,angle: CGFloat,radius: CGFloat) {
var radAngle = angle.radians
let textSize = text.boundingRect(
with: CGSize(width: .max,height: .max),options: [.usesLineFragmentOrigin,.usesFontLeading],context: nil)
.integral
.size
let perimeter: CGFloat = 2 * .pi * radius
let textAngle: CGFloat = textSize.width / perimeter * 2 * .pi
var textRotation: CGFloat = 0
var textDirection: CGFloat = 0
if angle > CGFloat(10).radians,angle < CGFloat(170).radians {
// bottom string
textRotation = 0.5 * .pi
textDirection = -2 * .pi
radAngle += textAngle / 2
} else {
// top string
textRotation = 1.5 * .pi
textDirection = 2 * .pi
radAngle -= textAngle / 2
}
for c in 0..<text.length {
let letter = text.attributedSubstring(from: NSRange(c..<c+1))
let charSize = letter.boundingRect(
with: CGSize(width: .max,context: nil)
.integral
.size
let letterAngle = (charSize.width / perimeter) * textDirection
let x = radius * cos(radAngle + (letterAngle / 2))
let y = radius * sin(radAngle + (letterAngle / 2))
let singleChar = drawText(
on: layer,text: letter,frame: CGRect(
x: (layer.frame.size.width / 2) - (charSize.width / 2) + x,y: (layer.frame.size.height / 2) - (charSize.height / 2) + y,width: charSize.width,height: charSize.height))
layer.addSublayer(singleChar)
singleChar.transform = CATransform3DMakeAffineTransform(CGAffineTransform(rotationAngle: radAngle - textRotation))
radAngle += letterAngle
}
}
func drawText(on layer: CALayer,frame: CGRect) -> CATextLayer {
let textLayer = CATextLayer()
textLayer.frame = frame
textLayer.string = text
textLayer.alignmentMode = CATextLayerAlignmentMode.center
textLayer.contentsScale = UIScreen.main.scale
return textLayer
}