Swift - Playground - Core Graphics / Core Text / Custom View
core-graphics, core-text, ios, swift, xcode
Solution
I wrote a utility function for my app to draw text using `CoreText`. It returns the text size for further processing:
func drawText(context: CGContextRef, text: NSString, attributes: [String: AnyObject], x: CGFloat, y: CGFloat) -> CGSize {
let font = attributes[NSFontAttributeName] as UIFont
let attributedString = NSAttributedString(string: text, attributes: attributes)
let textSize = text.sizeWithAttributes(attributes)
// y: Add font.descender (its a negative value) to align the text at the baseline
let textPath = CGPathCreateWithRect(CGRect(x: x, y: y + font.descender, width: ceil(textSize.width), height: ceil(textSize.height)), nil)
let frameSetter = CTFramesetterCreateWithAttributedString(attributedString)
let frame = CTFramesetterCreateFrame(frameSetter, CFRange(location: 0, length: attributedString.length), textPath, nil)
CTFrameDraw(frame, context)
return textSize
}
Call it like so:
var textAttributes: [String: AnyObject] = [
NSForegroundColorAttributeName : UIColor(white: 1.0, alpha: 1.0).CGColor,
NSFontAttributeName : UIFont.systemFontOfSize(17)
]
drawText(ctx, text: "Hello, World!", attributes: textAttributes, x: 50, y: 50)
Hope that helps you.
Problem
Question I'm attempting to make a custom UIView component in swift playground. I've been able to figure out how to do everything except for render text correctly. I'm not sure if i'm supposed to do this via Core Graphics or Core Text or exactly how to get it working correctly. As you can see in the image below I want to render text both upside down and right side up on either side of my custom View Component I've tried various ways to get the text to work but I keep running aground. If somebody would be able to show me how to modify my playground to add a few text rendering that would be awesome. Playground Code ``` // Playground - noun: a place where people can play import Foundation import UIKit class RunwayView : UIView { var northText : String? var southText : String? ///Draws the "runway" override func drawRect(rect: CGRect) { // Setup graphics context var ctx = UIGraphicsGetCurrentContext() // clear context CGContextClearRect(ctx, rect) let parentVieBounds = self.bounds let width = CGRectGetWidth(parentVieBounds) let height = CGRectGetHeight(parentVieBounds) // Setup the heights let endZoneHeight : CGFloat = 40 /* Remember y is negative and 0,0 is upper left*/ //Create EndZones CGContextSetRGBFillColor(ctx, 0.8, 0.8, 0.8, 1) CGContextFillRect(ctx, CGRectMake(0, 0, width, endZoneHeight)) CGContextFillRect(ctx, CGRectMake(0, height-endZoneHeight, width, endZoneHeight)) var northString = NSMutableAttributedString(string: "36") var attrs = [NSFontAttributeName : UIFont.systemFontOfSize(16.0)] var gString = NSMutableAttributedString(string:"g", attributes:attrs); var line = CTLineCreateWithAttributedString(gString) CGContextSetTextPosition(ctx, 10, 50); CTLineDraw(line, ctx); // Clean up } } var outerFrame : UIView = UIView(frame: CGRectMake(20,20,400,400)) var runway1 : RunwayView = RunwayView(frame: CGRectMake(0,0,30,260)) var runway2 : RunwayView = RunwayView(frame: CGRectMake(80,0,30,340)) runway1.transform = CGAffineTransformConcat(CGAffineTransformMakeTranslation(20, 200), CGAffineTransformMakeRotation(-0.785398163)) outerFrame.addSubview(runway1) runway2.transform = CGAffineTransformConcat(CGAffineTransformMakeTranslation(120, 140), CGAffineTransformMakeRotation(-0.585398163)) outerFrame.addSubview(runway2) outerFrame.backgroundColor = UIColor.yellowColor() outerFrame.clipsToBounds = true // View these elements runway1 outerFrame runway1 ```