问题
I'm woking on a project were I have to draw strings of text in a UIView. The problem is not drawing the Strings, but rotating them. I want the text to be drawn just above and at the same angle as the red line. Check illustration below:
illustration example:
Here is the code... (PS. All irrelevant code is removed)
class DrawView: UIView {
override func draw(_ rect: CGRect) {
let context = UIGraphicsGetCurrentContext()!
// Adding a line here.
context.move(to: CGPoint(x: 290, y: 650))
context.addLine(to: CGPoint(x: 530, y: 530))
context.strokePath()
// Flipping the coordinate system
context.textMatrix = .identity
context.translateBy(x: 0, y: bounds.size.height)
context.scaleBy(x: 1.0, y: -1.0)
// Creating the text path.
let path = CGMutablePath()
// "x" and "y" equals the staring point of the line. "width" equals the length of the line.
path.addRect(CGRect(x: 290, y: 650, width: 268, height: 30))
// I have tried rotating with the method below, but it rotates with the anchor point at (0, 0) in the UIView.
//context.rotate(by: 0.4636) // 0.4636 equals the angle of the red line in radians.
// Setting the text justification to center.
let justification = NSMutableParagraphStyle()
justification.alignment = NSTextAlignment.center
// Creating the attribute.
let attribute = [NSAttributedStringKey.font: UIFont(name: "Arial", size: 22.0)!,
NSAttributedStringKey.foregroundColor: UIColor.black,
NSAttributedStringKey.paragraphStyle: justification] as [NSAttributedStringKey : Any]?
// Creating the string and setting up the frame.
let attrString = NSAttributedString(string: "12032.00", attributes: attribute)
let framesetter = CTFramesetterCreateWithAttributedString(attrString as CFAttributedString)
let frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, attrString.length), path, nil)
CTFrameDraw(frame, context)
}
}
回答1:
Thanks to all of you I have finally figured it out, much thanks to @Grimxn. This is how I solved it:
// Set attributes.
let attribute = [NSAttributedStringKey.font: UIFont(name: "Courier", size: 22.0)!] as [NSAttributedStringKey : Any]?
// Save current context.
context.saveGState()
// Move orgin.
context.translateBy(x: 290, y: 650)
// Rotate the coordinate system.
context.rotate(by: -0.4636)
// Create a string.
let str = "12300.10"
// Draw string.
str.draw(at: CGPoint(x: 0, y: 0), withAttributes: attribute)
// Restore to saved context.
context.restoreGState()
回答2:
Rotation is always done at the current 0,0 point. If you want to rotate around a different center, you have to shift your matrix to put the desired point of rotation over the origin, rotate, and shift back.
来源:https://stackoverflow.com/questions/50604430/how-do-i-draw-an-nsattributedstring-rotated-around-a-specific-point