Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift - Playground - Core Graphics / Core Text / Custom View

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

enter image description here

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
like image 904
Jeef Avatar asked Nov 21 '14 01:11

Jeef


1 Answers

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.

like image 194
zisoft Avatar answered Nov 14 '22 21:11

zisoft