如果你想畫一個像這樣的字符串,子類NSLayoutManager
和覆蓋-drawGlyphsForGlyphRange:atPoint:
,在其中設置有CGAffineTransformMakeScale(-1, 1))
發送-showCGGlyphs:positions:count:font:matrix:attributes:inContext:
之前,在當前背景下的文本矩陣。 快速樣品重寫-drawGlyphsForGlyphRange:atPoint:
繪製文本 「顛倒」,但不採取型動物的保健屬性,如下劃線,strikethoughs ...
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// setup text objects
NSTextStorage *textStorage = [[NSTextStorage alloc] initWithString:[@"Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." stringByReversingString]];
MyLayoutManager *textLayout = [[MyLayoutManager alloc] init];
[textStorage addLayoutManager:textLayout];
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:self.view.bounds.size];
[textLayout addTextContainer:textContainer];
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(0,20,self.view.bounds.size.width,self.view.bounds.size.height-20)
textContainer:textContainer];
[self.view addSubview:textView];
}
@end
@implementation MyLayoutManager
- (void)drawGlyphsForGlyphRange:(NSRange)glyphsToShow atPoint:(CGPoint)origin
{
NSUInteger i;
CGContextRef ctx = UIGraphicsGetCurrentContext();
NSRange lineRange;
for (i = glyphsToShow.location; i < NSMaxRange(glyphsToShow); i = NSMaxRange(lineRange))
{
CGRect lineRect = [self lineFragmentRectForGlyphAtIndex:i effectiveRange:&lineRange];
NSRange characterRange = [self characterRangeForGlyphRange:lineRange actualGlyphRange:NULL];
/* This sample don't take care of different font attributes (size, etc ..) for the each lines */
UIFont *font = [[self.textStorage attributesAtIndex:characterRange.location effectiveRange:NULL] objectForKey:NSFontAttributeName];
UIColor *color = [[self.textStorage attributesAtIndex:characterRange.location effectiveRange:NULL] objectForKey:NSForegroundColorAttributeName];
CGGlyph *glyphs = malloc(sizeof(CGGlyph) * lineRange.length);
CGSize *advances = malloc(sizeof(CGSize) * lineRange.length);
[self getGlyphsInRange:lineRange glyphs:glyphs properties:NULL characterIndexes:NULL bidiLevels:NULL];
CTFontGetAdvancesForGlyphs((CTFontRef)font, kCTFontHorizontalOrientation, glyphs, advances, lineRange.length);
[color set];
CGFontRef cgfont = CTFontCopyGraphicsFont((CTFontRef)font, NULL);
// setup CGContextRef to draw text "upside-down"
CGAffineTransform textMatrix = CGAffineTransformMakeScale(-1, 1);
CGContextSetFont(ctx, cgfont);
CGContextSetFontSize(ctx, [font pointSize]);
CGContextSetTextMatrix(ctx, textMatrix);
CGPoint position = lineRect.origin;
position.x += origin.x;
position.y += origin.y;
int j;
/* if you want the text to be right align, like the 'Lorem ipsum dolor' screenshot */
#if 1
position.x += lineRect.size.width;
#else
/* if you want the text to be left align */
for (j = 0; j < characterRange.length; j++)
{
position.x += advances[j].width;
}
#endif
for (j = characterRange.length - 1; j >= 0; j--)
{
[self showCGGlyphs:&glyphs[j] positions:&position count:1 font:font matrix:textMatrix attributes:nil inContext:ctx];
position.x -= advances[j].width;
}
CGFontRelease(cgfont);
free(glyphs);
free(advances);
}
}
@end
![text "upside-down" right aligned](https://i.stack.imgur.com/x5h6L.png)
˙uʍop-ǝpısdn對ɹoʇıuoɯɹnoʎ ǝɥʇǝɥʇǝɥʇɥʇɥʇɐǝɹɐɐʎɟI –
@MartinR就是這樣。但是,如何以編程方式做到這一點? :D – motionpotion