前言
平时使用UILabel 的时候,默认都是横排排列。
现在需要竖排排列,暂时想到以下三种方法,大家可以留言补充。
实现效果:
1.\n 添加换行符号
遍历字符串,在每一个字符后面添加\n
此处,就直接在字符后写\n,上述代码自行脑补,嘿嘿。
[lab setNumberOfLines:0];
[lab setText:@"不\n忘\n初\n心\n,\n方\n得\n始\n终\n。"];
2.设置label 合适的宽度和长度,自动换行
UILabel *lab = [[UILabel alloc]initWithFrame:CGRectMake(12, 100, 16, 200)];
[lab setNumberOfLines:0];
[lab setText:@"不忘初心,方得始终。"];
[lab setTextColor:[UIColor redColor]];
[lab setTextAlignment:NSTextAlignmentCenter];
[lab setFont:[UIFont systemFontOfSize:15.0f]];
[self.view addSubview:lab];
这种方法比较取巧,姑且算一种方法吧。
3.NSVerticalGlyphFormAttributeName
你一定会在网上看到kCTVerticalFormsAttributeName,现在使用NSAttributedStringKey 对应到是上述方法。但是,不看注释的后果是,这个方法试了好久,不管用!!!
Currently on iOS, it's always horizontal 在iOS上,总是水平的。
NSMutableAttributedString *aa = [[NSMutableAttributedString alloc]initWithString:@"不忘初心,方得始终。"];
[aa addAttribute:(id)NSShadowAttributeName value:shadow range:NSMakeRange(0, [aa length])];
NSNumber *num = [NSNumber numberWithInteger:1];
[aa addAttribute:(id)NSVerticalGlyphFormAttributeName value:num range:NSMakeRange(0, [aa length])];
[lab setAttributedText:aa];
所以,即使设置了这个属性,也不起作用。pass!
3.draw
此处我们可以使用CoreText绘制富文本,CoreText的主要作用是用于文字的排版和渲染,如果我们需要将文本内容直接渲染到图形上下文(Graphics context)时,从性能和易用性来考虑,最佳方案就是使用CoreText。
对于CoreText 不了解的,可以先阅读下面文章:
CoreText实现图文混排
汉字的竖排排列
#import "VerticalGlyphLabel.h"
#import <CoreText/CoreText.h>
@implementation VerticalGlyphLabel
- (void)drawRect:(CGRect)rect{
[super drawRect:rect];
CGContextRef context = UIGraphicsGetCurrentContext();//获取当前绘制上下文
CGContextSetTextMatrix(context, CGAffineTransformIdentity);//设置字形的变换矩阵为不做图形变换
CGContextTranslateCTM(context, 0, self.bounds.size.height);//平移方法,将画布向上平移一个屏幕高
CGContextScaleCTM(context, 1.0, -1.0);//缩放方法,x轴缩放系数为1,则不变,y轴缩放系数为-1,则相当于以x轴为轴旋转180度
NSMutableAttributedString * attributeStr = [[NSMutableAttributedString alloc] initWithString:@"我是一个富文本"];
[attributeStr setAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15.0f]} range:NSMakeRange(0, [attributeStr length])];
CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attributeStr);//一个frame的工厂,负责生成frame
CGMutablePathRef path = CGPathCreateMutable();//创建绘制区域
CGPathAddRect(path, NULL, CGRectMake(0, 0, 20, self.bounds.size.height ));//添加绘制尺寸
NSInteger length = attributeStr.length;
CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0,length), path, NULL);//工厂根据绘制区域及富文本(可选范围,多次设置)设置frame
CTFrameDraw(frame, context);//根据frame绘制文字
CFRelease(frame);
CFRelease(path);
CFRelease(frameSetter);
}
上述方法其实和方法2类似,CGPathAddRect(path, NULL, CGRectMake(0, 0, 20, self.bounds.size.height ));添加绘制的尺寸,此处设置文字宽度和整体高度,就可以实现竖排的效果。
还有一种方法是在stackoverflow 的评论中看到的
using CoreText (to get glyphs) and CoreGraphics (to draw CGGlyphs)
NSMutableAttributedString * attributeStr = [[NSMutableAttributedString alloc] initWithString:@"this is a text" attributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:11.0f]}];
CGPoint location = CGPointMake(20, 20);
UIFont *font = [[attributeStr attributesAtIndex:0 effectiveRange:NULL] objectForKey:NSFontAttributeName];
NSUInteger myLength = [attributeStr length];
CTFontRef ctfont = CTFontCreateWithName((CFStringRef)[font fontName], [font pointSize], NULL);
CGGlyph *glyphs = malloc(sizeof(CGGlyph) * myLength);
UniChar *characters = malloc(sizeof(UniChar) * myLength);
CGSize *advances = malloc(sizeof(CGSize) * myLength);
[[attributeStr string] getCharacters:characters range:NSMakeRange(0,myLength)];
CTFontGetGlyphsForCharacters(ctfont, characters, glyphs, myLength);
CTFontGetAdvancesForGlyphs(ctfont, kCTFontOrientationHorizontal, glyphs, advances, myLength);
free(characters);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGFontRef cgfont = CTFontCopyGraphicsFont(ctfont, NULL);
CGContextSetFont(ctx, cgfont);
CGContextSetFontSize(ctx, CTFontGetSize(ctfont));
CGAffineTransform textMatrix = CGAffineTransformMakeTranslation(location.x, location.y);
textMatrix = CGAffineTransformScale(textMatrix, 1, -1);
CGContextSetTextMatrix(ctx, textMatrix);
CGFloat lineHeight = CTFontGetAscent(ctfont) + CTFontGetDescent(ctfont) + CTFontGetLeading(ctfont);
location.y = -CTFontGetAscent(ctfont);
CGFloat maxAdvance = 0.;
NSUInteger i;
for (i = 0; i < myLength; i++)
maxAdvance = MAX(maxAdvance, advances[i].width);
for (i = 0; i < myLength; i++)
{
location.x = (maxAdvance - advances[i].width) * 0.5;
CGContextShowGlyphsAtPositions(ctx, &glyphs[i], &location, 1);
location.y -= lineHeight;
}
free(glyphs);
free(advances);
CGFontRelease(cgfont);
CFRelease(ctfont);
其中需要CGGlyph数组。意思是你需要自己把unichar字符自已映射成字体文件中的Glyph。
如果需要使用汉字,此种方法是不行的,需要定制字体,关于字体定制请看
iOS 定制应用程序字体
后面两种方法都比较复杂,在此处有些小题大作了。
以上方法如有不正之处,请指出,谢谢。