Reputation: 30276
I'm using core text API to draw text on UI. (I don't know other methods, because most Google search results lead me to core text api).
I have read some tutorials online about using core text API. In those tutorial, I see step by step to config from matrix, attribute string to framesetter ... but none of them explain carefully meaning of each step, so I cannot modify by myself.
Below code is the function draw text on screen with (x,y)
is the location which I want to draw. This piece of code describe clearly step by step do draw on screen. Nevertheless I don't know where to put x and y parameters, so text will start to draw at this point in rectangle.
// draw text on screen.
+ (void)drawText:(CGContextRef)context bound:(CGRect)rect text:(NSString *)text x:(float)x y:(float) y color:(UIColor *)color size:(float)textSize{
CGContextSaveGState(context);
// always remember to reset the text matrix before drawing.
// otherwise the result will be unpredictable like using uninitialize memory
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CGContextSetTextMatrix(context, CGAffineTransformMakeScale(1.0f, -1.0f));
// Flip the coordinate system. because core Text uses different coordinate system with UI Kit
CGContextTranslateCTM(context, 0, rect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
// step 1: prepare attribute string
NSDictionary *attributes;
attributes = @{
(NSString *) kCTFontAttributeName : [UIFont fontWithName:@"Helvetica" size:textSize],
(NSString *) kCTForegroundColorAttributeName : color
};
NSAttributedString *str = [[NSAttributedString alloc]
initWithString:text attributes:attributes];
CFAttributedStringRef attrString = (__bridge CFAttributedStringRef)str;
// step 2: create CTFFrameSetter
CTFramesetterRef framesetter =
CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attrString);
// step 3. create CGPath
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, rect);
// step 4. get the frame
// use the CGPath and CTFrameSetter to create CTFrame. then drawn it in currently context
CTFrameRef frame = CTFramesetterCreateFrame
(framesetter, CFRangeMake(0, 0), path, NULL);
CTFrameDraw(frame, context);
// step 5. release resource
//CFRelease(attrString);
CFRelease(framesetter);
CFRelease(frame);
CFRelease(path);
CGContextRestoreGState(context);
}
Moreover, I see there are function: CGContextSetTextPosition
This seem what I need, but where should I put in above code. I have tried some, but no succeed. Please tell me how to fix this.
Thanks :)
Upvotes: 5
Views: 15676
Reputation: 105
On draw text selected view you can used UIView touch events as below. create global variable for Touch start point and Touch end Point as below
CGPoint startingPoint;
CGPoint endingPoint;
And then draw text or line as below
#pragma mark- Touch Event
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
startingPoint = [touch locationInView:self];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
}
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
endingPoint = [touch locationInView:self];
[self makeLineLayer:self.layer lineFromPointA:startingPoint
toPointB:endingPoint];
}
-(void)makeLineLayer:(CALayer *)layer lineFromPointA:(CGPoint)pointA
toPointB:(CGPoint)pointB
{
CAShapeLayer *line = [CAShapeLayer layer];
UIBezierPath *linePath=[UIBezierPath bezierPath];
[linePath moveToPoint: pointA];
[linePath addLineToPoint:pointB];
line.path=linePath.CGPath;
line.fillColor = nil;
line.opacity = 2.0;
line.lineWidth = 4.0;
line.strokeColor = [UIColor redColor].CGColor;
[layer addSublayer:line];
}
Upvotes: 1
Reputation: 11233
Although this thread is a bit old, but this is my work around for future visitors. This work requires a little bit modification and it starts moving the text to position (x, y).
You have to change step 3 like this:
// step 3. create CGPath
CGMutablePathRef path = CGPathCreateMutable();
CGRect newRect = rect;
newRect.origin.x = x;
newRect.origin.y = -y;
CGPathAddRect(path, NULL, newRect);
and the coordinate (x, y) will start working. The minus sign is due to the different axis of CoreTextAPI.
Also changed the TextMatrix to below for getting the correct transformation or it was giving a flipped Y-Axis text:
// always remember to reset the text matrix before drawing.
// otherwise the result will be unpredictable like using uninitialize memory
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CGContextSetTextMatrix(context, CGAffineTransformMakeScale(1.0f, 1.0f));
Attached screenshot from IB (Designable):
Hope it helps!
Upvotes: 0
Reputation: 13429
This is not CoreText solution but after your comment under your question I assume this would be a proper answer.
Basic text drawing on a view.
.h
#import <UIKit/UIKit.h>
@interface aView : UIView
@end
.m
#import "aView.h"
@implementation aView
- (void)drawText:(CGFloat)xPosition yPosition:(CGFloat)yPosition canvasWidth:(CGFloat)canvasWidth canvasHeight:(CGFloat)canvasHeight
{
//Draw Text
CGRect textRect = CGRectMake(xPosition, yPosition, canvasWidth, canvasHeight);
NSMutableParagraphStyle* textStyle = NSMutableParagraphStyle.defaultParagraphStyle.mutableCopy;
textStyle.alignment = NSTextAlignmentLeft;
NSDictionary* textFontAttributes = @{NSFontAttributeName: [UIFont fontWithName: @"Helvetica" size: 12], NSForegroundColorAttributeName: UIColor.redColor, NSParagraphStyleAttributeName: textStyle};
[@"Hello, World!" drawInRect: textRect withAttributes: textFontAttributes];
}
- (void)drawRect:(CGRect)rect {
[self drawText:0 yPosition:0 canvasWidth:200 canvasHeight:150];
}
@end
Upvotes: 13
Reputation: 1269
Starting with IOS 7 you can have the str render itself into the current context. To do this import UIKit. This will extend the defenition of NSAttributedString with drawAtPoint: method. So for example you might do something like this:
[str drawAtPoint:CGPointMake(x,y)]
For more info about this and other related methods please see the following: https://developer.apple.com/library/ios/documentation/uikit/reference/NSAttributedString_UIKit_Additions/Reference/Reference.html#//apple_ref/occ/instm/NSAttributedString/drawAtPoint:
Upvotes: 3