NSLayoutManager: вызов setLocation: forStartOfGlyphRange: не изменяет положение нарисованного глифа

Я создал простой подкласс NSLayoutManager, который должен позволить мне изменить начало первых глифов для заданного диапазона:

@implementation GRZCategoryLinkLayoutManager

- (void)invalidateLayoutForCharacterRange:(NSRange)charRange actualCharacterRange:(NSRangePointer)actualCharRange {
    [super invalidateLayoutForCharacterRange:charRange actualCharacterRange:actualCharRange];

    NSRange glyphRange = [self glyphRangeForCharacterRange:charRange actualCharacterRange:nil];
    CGPoint firstGlyphLocation = [self locationForGlyphAtIndex:glyphRange.location];
    firstGlyphLocation.x += 100;

    NSLog(@"%@", NSStringFromCGPoint([self locationForGlyphAtIndex:glyphRange.location]));
    // {100, 0}

    [self setLocation:firstGlyphLocation forStartOfGlyphRange:glyphRange];

    NSLog(@"%@", NSStringFromCGPoint([self locationForGlyphAtIndex:glyphRange.location]));
    // {200, 0}

}

Судя по выходу журнала, местоположение глифа изменено. Но когда текст отображается через UITextView, глиф (и все последующие глифы) рисуется в {100, 0}. То же самое произойдет, если я нарисую текст в -drawRect:

- (void)drawRect:(CGRect)rect {
    NSMutableAttributedString *string = [self.textStorage mutableCopy];
    if (string && string.length > 0) {
        CGContextRef context = UIGraphicsGetCurrentContext();
        NSRange range = [self.layoutManager glyphRangeForTextContainer:self.textContainer];

        [self.layoutManager drawGlyphsForGlyphRange:range atPoint:CGPointMake(0, 0)];
    }
}

Я использовал пример кода из этого вопроса: NSLayoutManager: Calling setLocation(_:forStartOfGlyphRange: ) отключает кернинг во всей строке?

Кто-нибудь знает, почему глифы рисуются не в том месте?


person Tobias Kreß    schedule 13.01.2016    source источник


Ответы (1)


Я должен был прочитать документацию более внимательно.

«Этот метод используется механизмом компоновки и должен вызываться только во время набора текста, почти во всех случаях только менеджером компоновки. Например, его может вызывать пользовательский менеджер компоновки».

Я всегда вызывал setLocation в таких местах, как -viewDidLoad. Но расположение каждого глифа сбрасывается при наборе текста. И текст верстается каждый раз, когда меняется его рамка. При вызове setLocation в -viewDidLayoutSubviews все работает нормально.

person Tobias Kreß    schedule 14.01.2016