如何在iOS7中反转NSString变量中的文本? (我想颠倒显示文字)。 注意:有许多解决方案,其中UILabel或UITextView被颠倒翻转,但这不是我想要的。
目前我可以在一个反转字符串的类别中执行以下操作:
+ (NSString *)stringByReversingString:(NSString *)str
{
char cString[150];
char revString[150];
NSString *retval;
[str getCString:cString
maxLength:[str lengthOfBytesUsingEncoding:NSUTF8StringEncoding] + 1
encoding:NSUTF8StringEncoding];
for (int i = 0; i < strlen(cString); i++) {
revString[i] = cString[strlen(cString) - (i + 1)];
}
revString[strlen(cString)] = '\0';
retval = [NSString stringWithCString:revString encoding:NSUTF8StringEncoding];
return retval;
}
但我怎么会把文字翻过来呢?
答案 0 :(得分:4)
你不能显示一个字符串颠倒的纯字符串转换,你有 翻转包含字符串的视图。
某些 Unicode字符是“普通”字母的倒置版本, 比如
Ⅎ - TURNED CAPITAL F (U+2132)
但不适用于所有角色。 您只能使用http://www.fileformat.info/convert/text/upside-down-map.htm这样的表模仿翻转:
uʍop-ǝpısdn sı ɹoʇıuoɯ ɹnoʎ uǝɥʇ sıɥʇ pɐǝɹ uɐɔ noʎ ɟI
(使用http://www.fileformat.info/convert/text/upside-down.htm创建)
但请注意,有些字母只有非常粗略的倒置近似值, 比如
K --> ⋊ - RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT (U+22CA)
许多角色根本没有任何东西。所以这适合一些有趣的展示, 但不是生产应用程序。更好地翻转视图。
答案 1 :(得分:2)
如果你想绘制这样的字符串,子类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