Snowman
Snowman

Reputation: 32071

Drawing NSAttributedString with Core Text centered

I have a method that draws an NSAttributedString in a rect:

-(void)drawInRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge  CFAttributedStringRef)self);

    // left column form
    CGMutablePathRef leftColumnPath = CGPathCreateMutable();
    CGPathAddRect(leftColumnPath, NULL, CGRectMake(rect.origin.x, -rect.origin.y, rect.size.width, rect.size.height));

    // left column frame
    CGFloat translateAmount = rect.size.height;
    CGContextSetTextMatrix(context, CGAffineTransformIdentity);
    CGContextTranslateCTM(context, 0, translateAmount);
    CGContextScaleCTM(context, 1.0, -1.0);
    CTFrameRef leftFrame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), leftColumnPath, NULL);

    CTFrameDraw(leftFrame, context);

    CGContextSetTextMatrix(context, CGAffineTransformIdentity);
    CGContextTranslateCTM(context, 0, translateAmount);
    CGContextScaleCTM(context, 1.0, -1.0);

    CFRelease(leftFrame);
    CFRelease(framesetter);
    CGPathRelease(leftColumnPath);
}

I put this together a couple months ago with some help from tutorials. It turns out though that this, by default, draws the string left aligned. I'm not too crafty with Core Text, does anyone know how I might be able to draw this with text alignment center?

(Please don't recommend outside label drawing class, I need to do this with Core Text).

Upvotes: 3

Views: 4271

Answers (2)

ingconti
ingconti

Reputation: 11646

for swift 3.0:

final private func drawIn(rect: CGRect, attribString: NSAttributedString ){

        guard let context = UIGraphicsGetCurrentContext() else{
            return
        }

        let framesetter = CTFramesetterCreateWithAttributedString(attribString)

        // left column form
        let leftColumnPath = CGMutablePath()
        leftColumnPath.addRect(CGRect(x:rect.origin.x,
                                      y: -rect.origin.y,
                                      width: rect.size.width,
                                      height: rect.size.height)
        )

        // left column frame
        let translateAmount = rect.size.height

        context.saveGState()
        context.textMatrix = CGAffineTransform.identity

        context.translateBy(x: 0, y: translateAmount)
        context.scaleBy(x: 1.0, y: -1.0)
        let leftFrame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), leftColumnPath, nil)

        CTFrameDraw(leftFrame, context)

        context.textMatrix = CGAffineTransform.identity
        context.translateBy(x: 0, y: translateAmount)
        context.scaleBy(x: 1.0, y: -1.0)
    }


    final private func drawStopMessage(){

        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.alignment = .center


        let attributes = [NSParagraphStyleAttributeName :  paragraphStyle,
                          NSFontAttributeName :   UIFont.systemFont(ofSize: 24.0),
                          NSForegroundColorAttributeName : UIColor.blue,
                          ]

        let attrString = NSAttributedString(string: "Stop\nall Dance",
                                       attributes: attributes)


        let rect = CGRect(x: 20, y: 100, width: 300, height: 300)
        drawIn(rect: rect, attribString: attrString)
    }

Upvotes: 2

justin
justin

Reputation: 104698

Set the CTTextAlignment of the CTParagraphStyle to kCTCenterTextAlignment for the range of the attributed string you want centered.

Then create the CTFramesetter, then draw.


Example: http://foobarpig.com/iphone/coretext-set-text-font-and-alignment-to-cfattributedstring.html

Upvotes: 3

Related Questions