Как сделать растянутый текст в iOS? - PullRequest
9 голосов
/ 09 марта 2011

Учитывая прямоугольную область, я хочу визуализировать некоторый текст, используя определенный шрифт, и чтобы отображаемый текст заполнял прямоугольник . Как на картинке ниже:

enter image description here

  1. Это не то же самое, что просто изменить размер шрифта
  2. Рендеринг в виде растрового изображения с последующим масштабированием - не вариант (выглядит ужасно)
  3. Векторная графика - способ сделать это

Решение

Я придумал следующее, которое, кажется, работает для моих целей. Код рисует одну строку масштабирования текста, чтобы заполнить границы. Подкласс UIView и заменить drawRect следующим образом.

- (void)drawRect:(CGRect)rect 
{
    [self drawScaledString:@"Abcde"]; 
}

- (void)drawScaledString:(NSString *)string
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetTextMatrix(context, CGAffineTransformIdentity);

    NSAttributedString *attrString = [self generateAttributedString:string];

    CFAttributedStringSetAttribute((CFMutableAttributedStringRef)attrString, CFRangeMake(0, string.length), 
                                   kCTForegroundColorAttributeName, [UIColor redColor].CGColor);

    CTLineRef line = CTLineCreateWithAttributedString((CFAttributedStringRef) attrString);

    // CTLineGetTypographicBounds doesn't give correct values, 
    // using GetImageBounds instead
    CGRect imageBounds = CTLineGetImageBounds(line, context);
    CGFloat width = imageBounds.size.width;
    CGFloat height = imageBounds.size.height;

    CGFloat padding = 0;

    width += padding;
    height += padding;

    float sx = self.bounds.size.width / width;
    float sy = self.bounds.size.height / height;

    CGContextSetTextMatrix(context, CGAffineTransformIdentity);

    CGContextTranslateCTM(context, 1, self.bounds.size.height);
    CGContextScaleCTM(context, 1, -1);
    CGContextScaleCTM(context, sx, sy);

    CGContextSetTextPosition(context, -imageBounds.origin.x + padding/2, -imageBounds.origin.y + padding/2);

    CTLineDraw(line, context);
    CFRelease(line);
}

- (NSAttributedString *)generateAttributedString:(NSString *)string
{

    CTFontRef helv = CTFontCreateWithName(CFSTR("Helvetica-Bold"),20, NULL);
    CGColorRef color = [UIColor blackColor].CGColor;

    NSDictionary *attributesDict = [NSDictionary dictionaryWithObjectsAndKeys:
                                    (id)helv, (NSString *)kCTFontAttributeName,
                                    color, (NSString *)kCTForegroundColorAttributeName,
                                    nil];

    NSAttributedString *attrString = [[[NSMutableAttributedString alloc]
                                   initWithString:string
                                        attributes:attributesDict] autorelease];

    return attrString;
}

Пример использования:

CGRect rect = CGRectMake(0, 0, 50, 280);
MyCTLabel *label = [[MyCTLabel alloc] initWithFrame:rect];
label.backgroundColor = [UIColor whiteColor]; 
[self addSubview:label];

Ответы [ 3 ]

5 голосов
/ 09 марта 2011

Вы можете установить свойство преобразования UILabel и масштабировать ширину:

[myLabel sizeToFit];
myLabel.transform = CGAffineTransformMakeScale(0.5, 1.0);
2 голосов
/ 09 марта 2011

Вы можете попробовать CoreText. Получите CTFramesetter, вычислите его прямоугольник, затем вычислите аффинное преобразование, необходимое для сжатия этого прямоугольника в требуемые границы, и установите его в качестве CTM. Затем, когда вы рисуете текст, он должен растягиваться соответствующим образом с полным качеством.

0 голосов
/ 09 марта 2011

вы также можете попробовать с UILabel @property(nonatomic) BOOL adjustsFontSizeToFitWidth и @property minimumFontSize

Изначально вы можете установить гораздо более высокое значение для свойства шрифта, а также инициализировать minimumFontSize с минимальным значением шрифта.

...