核心文本 - 文本的位置不正确

时间:2014-01-19 17:27:57

标签: ios core-text

这是我第一次使用核心图形和文本,因此可能会做一些非常简单的事情。我一直在阅读文档,试着看看我哪里出错了但是看不到它,所以想知道是否有人可以帮我发现问题。

我正在尝试在屏幕顶部绘制一个简单的小信息横幅,但我想要在横幅中显示的文字并未绘制在正确的位置。

在我看来,我正在按如下方式创建我的控件:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    self.banner = [[Banner alloc] initWithFrame:CGRectMake(0,20,768,200)];
    [self.view addSubview:self.banner];
}

控制代码如下:

#import <CoreText/CoreText.h>

#import "Banner.h"

@implementation Banner

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        self.backgroundColor = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1];
    }
    return self;
}


// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    // Get the graphics context.
    CGContextRef context = UIGraphicsGetCurrentContext();

    // Draw the banner border.
    CGContextSaveGState(context);

    UIColor *strokeColor = [UIColor blackColor];
    CGContextSetStrokeColorWithColor(context, strokeColor.CGColor);
    CGContextSetLineWidth(context, 5);
    CGContextStrokeRect(context, CGRectMake(2,2,self.frame.size.width -4,100));

    CGContextRestoreGState(context);


    // Setup the text label & value.
    NSString *addressLabelText = @"Address";
    NSString *addressValue = @"123 Letsby Avenue\nSome Place\nSome City\nSome County\nSome Postcode";

    UIFont *font = [UIFont fontWithName:@"Helvetica" size:14.0];

    CGSize labelSize = [self getBoundsForString:addressLabelText usingFont:font];
    CGSize valueSize = [self getBoundsForString:addressValue usingFont:font];

    // So I want to Draw the label at X:10 Y:10 and the Value At X:65 Y:10
    // So we get Something like:
    // =============================
    // || Address 123 letsby avenue
    // ||         Some Place
    // ||         Some City
    // ||         Some County
    // ||         Some Postcode
    // =============================

    CGRect labelBounds = CGRectMake(10,10,labelSize.width,labelSize.height);
    // Move the address value over the margin width(10) + the label width + some spacing(5)
    CGRect valueBounds = CGRectMake(10 + labelSize.width + 5, 10, valueSize.width, valueSize.height);

    [self drawString: addressLabelText withFont: font inRect:labelBounds usingContext:context];
    [self drawString: addressValue withFont: font inRect:valueBounds usingContext:context];

    // The text hasn't drawn where i thought it should. Draw a rect there to make sure i had the right bounds
    UIColor *rectFillColor = [UIColor colorWithRed:0 green:0 blue:1 alpha:0.3];

    CGContextSaveGState(context);

    CGContextSetFillColorWithColor(context, [rectFillColor CGColor]);
    CGContextFillRect(context, labelBounds);
    CGContextFillRect(context, valueBounds);

    CGContextRestoreGState(context);
    //Hmm that is drawing in the right place. Whats going wrong with drawing the text.

    [self setNeedsDisplay];

}

-(void) drawString:(NSString*) string withFont:(UIFont*)font inRect:(CGRect)rect usingContext:(CGContextRef) context
{
    CGContextSaveGState(context);

    // flipping the coordinate system.
    CGContextTranslateCTM(context, 0, 200); // The control is rendered in a frame 200 high.
    CGContextScaleCTM(context, 1.0, -1.0);

    CGContextSetTextMatrix(context, CGAffineTransformIdentity);

    // Define the path we are going to draw the text on.
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddRect(path, NULL, rect);

    CFMutableAttributedStringRef attrString = CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);
    CFAttributedStringReplaceString (attrString, CFRangeMake(0, 0), (CFStringRef)string);

    // Create the framesetter with the attributed string.
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attrString);
    CFRelease(attrString);

    // Create a frame.
    CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);

    // Draw the specified frame in the given context.
    CTFrameDraw(frame, context);

    CGContextRestoreGState(context);

    CFRelease(frame);
    CFRelease(path);
    CFRelease(framesetter);
}

-(CGSize) getBoundsForString:(NSString *)string usingFont:(UIFont *)font
{
    return [string boundingRectWithSize:CGSizeMake(999,999)
                   options:NSStringDrawingUsesLineFragmentOrigin
                   attributes:[NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName]
                   context:nil].size;
}


@end

这样做的结果是在横幅中绘制了一些蓝色的字幕,我希望文字在那里,但文字实际上出现在横幅之外,我很困惑为什么。

https://www.dropbox.com/s/q2ap9tl4okaka49/Banner.png

1 个答案:

答案 0 :(得分:2)

我发现上面的代码似乎有用了......改变这个:

-(void) drawString:(NSString*) string withFont:(UIFont*)font inRect:(CGRect)rect usingContext:(CGContextRef) context
{
    CGContextSaveGState(context);

    // flipping the coordinate system.
    CGContextTranslateCTM(context, 0, 200); // The control is rendered in a frame 200 high.
    CGContextScaleCTM(context, 1.0, -1.0);

    CGContextSetTextMatrix(context, CGAffineTransformIdentity);

-(void) drawString:(NSString*) string withFont:(UIFont*)font inRect:(CGRect)rect usingContext:(CGContextRef) context
{
    CGContextSaveGState(context);

    // flipping the coordinate system.
    CGContextTranslateCTM(context, 0, rect.size.height+(2*rect.origin.y));
    CGContextScaleCTM(context, 1.0, -1.0);

以下行似乎没有任何改变。

    CGContextSetTextMatrix(context, CGAffineTransformIdentity);

改变这一行:

    CGContextTranslateCTM(context, 0, 200);

    CGContextTranslateCTM(context, 0, rect.size.height+(2*rect.origin.y));

将文本正确放置在我希望的位置....使用Xamarin和等效的c#我必须反转高度+ 2Y结果的结果:-S