iOS:在矩形中的某个点绘制文本

时间:2014-08-11 18:19:37

标签: ios objective-c core-text

我正在使用核心文本API在UI上绘制文本。 (我不知道其他方法,因为大多数Google搜索结果都会引导我使用核心文本api。)

我已经在线阅读了一些关于使用核心文本API的教程。在那些教程中,我逐步看到从矩阵,属性字符串到框架集的配置......但是没有一个仔细解释每个步骤的含义,所以我不能自己修改。

下面的代码是屏幕上的功能绘图文字,(x,y)是我想要绘制的位置。这段代码一目了然地在屏幕上绘制。不过我不知道在哪里放x和y参数,所以文本将开始在矩形中绘制。

// 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);
}

此外,我看到有功能:CGContextSetTextPosition这似乎是我需要的,但我应该把它放在上面的代码中。我尝试了一些,但没有成功。请告诉我如何解决这个问题。

谢谢:)

4 个答案:

答案 0 :(得分:11)

这不是CoreText解决方案,但根据您的问题发表评论后,我认为这将是一个正确的答案。

视图上的基本文字绘图。

·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

答案 1 :(得分:3)

从IOS 7开始,您可以将str渲染到当前上下文中。为此,请导入UIKit。这将使用drawAtPoint:方法扩展NSAttributedString的defenition。例如,您可能会这样做:

[str drawAtPoint:CGPointMake(x,y)]

有关此方法及其他相关方法的详细信息,请参阅以下内容: https://developer.apple.com/library/ios/documentation/uikit/reference/NSAttributedString_UIKit_Additions/Reference/Reference.html#//apple_ref/occ/instm/NSAttributedString/drawAtPoint

答案 2 :(得分:1)

在绘制文本选定的视图时,您可以如下使用UIView触摸事件。 如下所示为Touch起点和Touch终点创建全局变量

CGPoint startingPoint;
CGPoint endingPoint;

然后按如下所示绘制文本或线条

#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];
}

答案 3 :(得分:0)

虽然这个帖子有点旧,但这是我为未来的访问者所做的工作。这项工作需要稍加修改,然后开始将文本移动到位置(x,y)。

您必须更改第3步,如下所示:

// step 3. create CGPath
CGMutablePathRef path = CGPathCreateMutable();
CGRect newRect = rect;
newRect.origin.x = x;
newRect.origin.y = -y;
CGPathAddRect(path, NULL, newRect);

并且坐标(x,y)将开始工作。减号是由于CoreTextAPI的不同轴。

还将TextMatrix更改为下面以获得正确的转换,或者它是一个翻转的Y轴文本:

// 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));

IB(可设计)的附加截图:

Screenshot

希望它有所帮助!