Draw a Clock Face with Core Text
Few days ago, I was trying to solve an issue on stackoverflow: Core Text Rotation does not properly rotate - Swift.
Because Core Graphics and Core Text are not things that I usually do all the time, I put the codes below which is revised little bit as a record for review later.
import UIKit class ClockFace: UIView { func drawText(context: CGContextRef, text: String, attributes: [String: AnyObject], origin: CGPoint, angle: CGFloat) -> CGSize { let attributedString = NSAttributedString(string: text, attributes: attributes) let textSize = text.sizeWithAttributes(attributes) let font = attributes[NSFontAttributeName] as! UIFont let rect = CGRect(x: origin.x, y: origin.y + font.descender, width: ceil(textSize.width), height: ceil(textSize.height)) let textPath = CGPathCreateWithRect(rect, nil) let frameSetter = CTFramesetterCreateWithAttributedString(attributedString) let range = CFRange(location: 0, length: attributedString.length) let frame = CTFramesetterCreateFrame(frameSetter, range, textPath, nil) var transform = CGAffineTransformMakeTranslation(origin.x, origin.y + font.descender) transform = CGAffineTransformRotate(transform, angle) CGContextConcatCTM(context, transform); CTFrameDraw(frame, context) return textSize } override func drawRect(rect: CGRect) { let context = UIGraphicsGetCurrentContext()! let radius = rect.size.width/3 CGContextTranslateCTM(context, -radius, rect.size.height + 5) CGContextScaleCTM(context, 1, -1) let tilt = 6 CGContextRotateCTM(context, CGFloat((Double(tilt) / 360) * M_PI)) let attributes = [ NSForegroundColorAttributeName : UIColor.whiteColor(), NSFontAttributeName : UIFont.systemFontOfSize(12)] let origin = CGPoint(x: radius, y: 0) var number: Int = 2 for i in 0..<60 { CGContextSaveGState(context) CGContextTranslateCTM(context, rect.width/2, rect.height/2) CGContextRotateCTM(context, -CGFloat((Double(12 * i) / 360) * M_PI)) if (i % 5 == 0) { number++ number = number > 12 ? number - 12 : number drawText(context, text: "\(number)", attributes: attributes, origin: origin, angle: CGFloat((Double(12 * i - tilt) / 360) * M_PI)) } CGContextRestoreGState(context) } } } let view = ClockFace(frame: CGRectMake(0, 0, 150, 150)) import XCPlayground XCPlaygroundPage.currentPage.needsIndefiniteExecution = true XCPlaygroundPage.currentPage.liveView = view









