Базовый текст - неправильная позиция текста
Я впервые использую основную графику и текст, поэтому могу делать что-то очень простое, что неверно. Я читал документацию, чтобы попытаться понять, в чем проблема, но не вижу, поэтому удивляюсь, может ли кто-нибудь помочь мне определить проблему.
Я пытаюсь нарисовать простой маленький баннер с информацией в верхней части экрана, но текст, который я хочу отобразить на баннере, нарисован не в правильном месте.
На мой взгляд, я создаю свой контроль следующим образом:
- (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
В результате на баннере нарисованы синие штрихи, где я ожидал, что текст будет, но текст на самом деле появляется за пределами баннера, и я озадачен, почему.
1 ответ
Я нашел то, что работает для моего кода выше... изменив это:
-(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