I am using following class to create curved text to be added to a CALayer
class CurvedTextLayer: CALayer {
override init() {
super.init()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override init(layer: Any) {
super.init(layer: layer)
}
init(with bounds: CGRect) {
super.init()
self.frame = bounds
self.setNeedsDisplay()
}
func update(bounds: CGRect) {
self.frame = bounds
self.setNeedsDisplay()
}
override func draw(in ctx: CGContext) {
super.draw(in: ctx)
UIGraphicsPushContext(ctx)
ctx.translateBy(x: bounds.size.width / 2, y: bounds.size.height / 2)
ctx.scaleBy(x: 1, y: -1)
centreArcPerpendicular(text: "Hello round world", context: ctx, radius: 100, angle: 0, colour: UIColor.red, font: UIFont.systemFont(ofSize: 16), clockwise: true)
centreArcPerpendicular(text: "Anticlockwise", context: ctx, radius: 100, angle: CGFloat(-Double.pi/2), colour: UIColor.red, font: UIFont.systemFont(ofSize: 16), clockwise: false)
centre(text: "Hello flat world", context: ctx, radius: 0, angle: 0 , colour: UIColor.yellow, font: UIFont.systemFont(ofSize: 16), slantAngle: CGFloat(Double.pi/4))
UIGraphicsPopContext()
}
func centreArcPerpendicular(text str: String, context: CGContext, radius r: CGFloat, angle theta: CGFloat, colour c: UIColor, font: UIFont, clockwise: Bool){
let characters: [String] = str.map { String($0) }
let l = characters.count
let attributes = [NSAttributedString.Key.font: font]
var arcs: [CGFloat] = []
var totalArc: CGFloat = 0
for i in 0 ..< l {
arcs += [chordToArc(characters[i].size(withAttributes: attributes).width, radius: r)]
totalArc += arcs[i]
}
let direction: CGFloat = clockwise ? -1 : 1
let slantCorrection: CGFloat = clockwise ? -.pi / 2 : .pi / 2
var thetaI = theta - direction * totalArc / 2
for i in 0 ..< l {
thetaI += direction * arcs[i] / 2
centre(text: characters[i], context: context, radius: r, angle: thetaI, colour: c, font: font, slantAngle: thetaI + slantCorrection)
thetaI += direction * arcs[i] / 2
}
}
func chordToArc(_ chord: CGFloat, radius: CGFloat) -> CGFloat {
return 2 * asin(chord / (2 * radius))
}
func centre(text str: String, context: CGContext, radius r: CGFloat, angle theta: CGFloat, colour c: UIColor, font: UIFont, slantAngle: CGFloat) {
let attributes = [NSAttributedString.Key.foregroundColor: c, NSAttributedString.Key.font: font]
context.saveGState()
context.scaleBy(x: 1, y: -1)
context.translateBy(x: r * cos(theta), y: -(r * sin(theta)))
context.rotate(by: -slantAngle)
let offset = str.size(withAttributes: attributes)
context.translateBy (x: -offset.width / 2, y: -offset.height / 2)
str.draw(at: CGPoint(x: 0, y: 0), withAttributes: attributes)
context.restoreGState()
}
}
In ViewController I add the layer as follows
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let sublayer = CurvedTextLayer(with: myView.bounds)
myView.layer.insertSublayer(sublayer, at: 0)
animate()
}
After this I add this animation
func animate() {
let rotationAnimation = CABasicAnimation(keyPath: "transform.scale")
rotationAnimation.fromValue = 1
rotationAnimation.toValue = 2
rotationAnimation.duration = 3
rotationAnimation.fillMode = .forwards
rotationAnimation.isRemovedOnCompletion = false
myView.layer.add(rotationAnimation, forKey: "wateva")
}
After scaling I get this pixelated text.
How can I make it so that it doesn't look pixelated?
