简体   繁体   中英

NSLayoutManager: Calling setLocation:forStartOfGlyphRange: does not change the position of the drawn glyph

I created a simple NSLayoutManager subclass that should allow me to change the first glyphs origin for a given range:

@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}

}

According to the log output, the location of the glyph is changed. But when the text ist displayed via an UITextView , the glyph (and all the following glyphs) is drawn at {100, 0} . The same happens if I draw the text in -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)];
    }
}

I used the code example from this question: NSLayoutManager: Calling setLocation(_:forStartOfGlyphRange:) disables kerning in the whole string?

Does anyone have an idea why the glyphs get drawn at the wrong origin?

I should have read the documentation more carefully.

"This method is used by the layout mechanism and should be invoked only during typesetting, in almost all cases only by the layout manager. For example, a custom layout manager might invoke it."

I've always called setLocation in places like -viewDidLoad . But the location for each glyph is reseted when typesetting the text. And the text is typesetted each time its frame is changed. When calling setLocation in -viewDidLayoutSubviews everything works fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM