1.基础知识
lineHeight = ascent + descent + leading
2.文字垂直对齐方式
iOS文本容器中都是基线对齐,所谓的基线对齐就是指无论中文字符,数字,英文字符,表情等它们在一行的时候,基线是在同一高度的。
NSMutableParagraphStyle *ParagraphStyle = [[NSMutableParagraphStyle alloc] init];
ParagraphStyle.lineHeightMultiple = 1;
ParagraphStyle.lineSpacing = 0;
ParagraphStyle.paragraphSpacing = 0;
ParagraphStyle.paragraphSpacingBefore = 0;
NSDictionary *dic1 = @{NSFontAttributeName:[UIFont systemFontOfSize:30],
NSForegroundColorAttributeName:[UIColor blackColor],
NSBackgroundColorAttributeName:[UIColor yellowColor],
NSBaselineOffsetAttributeName:@0,
NSParagraphStyleAttributeName:ParagraphStyle
};
NSDictionary *dic2 = @{NSFontAttributeName:[UIFont systemFontOfSize:30],
NSForegroundColorAttributeName:[UIColor redColor],
NSBackgroundColorAttributeName:[UIColor yellowColor],
NSBaselineOffsetAttributeName:@0,
NSParagraphStyleAttributeName:ParagraphStyle
};
NSDictionary *dic3 = @{NSFontAttributeName:[UIFont systemFontOfSize:30],
NSForegroundColorAttributeName:[UIColor blueColor],
NSBackgroundColorAttributeName:[UIColor yellowColor],
NSBaselineOffsetAttributeName:@0,
NSParagraphStyleAttributeName:ParagraphStyle
};
NSMutableAttributedString *attributeStr1 = [[NSMutableAttributedString alloc] initWithString:@"柯晓琪" attributes:dic1];
NSAttributedString *attributeStr2 = [[NSAttributedString alloc] initWithString:@" 1234567890" attributes:dic2];
NSAttributedString *attributeStr3 = [[NSAttributedString alloc] initWithString:@" 😆jqLvQ" attributes:dic3];
[attributeStr1 appendAttributedString:attributeStr3];
[attributeStr1 appendAttributedString:attributeStr2];
NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
attachment.image = [UIImage imageNamed:@"tsj"];
attachment.bounds = CGRectMake(0,0,[UIFont systemFontOfSize:30].ascender,[UIFont systemFontOfSize:30].ascender);
[attributeStr1 appendAttributedString:[NSAttributedString attributedStringWithAttachment:attachment]];
CGRect rect = [attributeStr1 boundingRectWithSize:CGSizeMake(600, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:NULL];
NSLog(@"lineHeight : %f",[UIFont systemFontOfSize:30].lineHeight);
NSLog(@"pointSize : %f",[UIFont systemFontOfSize:30].pointSize);
NSLog(@"descender : %f",[UIFont systemFontOfSize:30].descender);
NSLog(@"ascender : %f",[UIFont systemFontOfSize:30].ascender);
NSLog(@"leading : %f",[UIFont systemFontOfSize:30].leading);
NSLog(@"descender + ascender + leading = %f",[UIFont systemFontOfSize:30].ascender - [UIFont systemFontOfSize:30].descender + [UIFont systemFontOfSize:30].leading);
NSLog(@"boundingRectWithSizeHeight : %f",rect.size.height);
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 100, 600, 100)];
label.attributedText = attributeStr1;
label.numberOfLines = 0;
[self.view addSubview:label];
/*
2018-03-12 14:00:34.619455+0800 JQ_textView[13941:5472023] lineHeight : 35.800781
2018-03-12 14:00:34.619537+0800 JQ_textView[13941:5472023] pointSize : 30.000000
2018-03-12 14:00:34.619556+0800 JQ_textView[13941:5472023] descender : -7.236328
2018-03-12 14:00:34.619573+0800 JQ_textView[13941:5472023] ascender : 28.564453
2018-03-12 14:00:34.619596+0800 JQ_textView[13941:5472023] leading : 0.000000
2018-03-12 14:00:34.619614+0800 JQ_textView[13941:5472023] descender + ascender + leading = 35.800781
2018-03-12 14:00:34.619627+0800 JQ_textView[13941:5472023] boundingRectWithSizeHeight : 35.800781
*/
pointSize和UIFont的字体大小一致
ascender是基线之上的高度,通常为正
decender是基线之下的高度,通常为负
descender + ascender + leading计算出的高度在没有行间距和段间距距并且lineHeightMultiple=1的情况下和boundingRectWithSizeHeight计算出的高度一致。
3.字体大小不同文本垂直居中
所以需要设置NSBaselineOffsetAttributeName属性,可以达到目的,注意descender是负值。
//NSBaselineOffsetAttributeName:@(([UIFont systemFontOfSize:30].lineHeight - [UIFont systemFontOfSize:15].lineHeight)/2 + (([UIFont systemFontOfSize:30].descender - [UIFont systemFontOfSize:15].descender))),
NSDictionary *dic1 = @{NSFontAttributeName:[UIFont systemFontOfSize:15],
NSForegroundColorAttributeName:[UIColor blackColor],
NSBackgroundColorAttributeName:[UIColor yellowColor],
NSBaselineOffsetAttributeName:@(([UIFont systemFontOfSize:30].lineHeight - [UIFont systemFontOfSize:15].lineHeight)/2 + (([UIFont systemFontOfSize:30].descender - [UIFont systemFontOfSize:15].descender))),
NSParagraphStyleAttributeName:ParagraphStyle
};
4.NSTextAttachment对齐
NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
attachment.image = [UIImage imageNamed:@"tsj"];
attachment.bounds = CGRectMake(0,0,[UIFont systemFontOfSize:30].ascender,[UIFont systemFontOfSize:30].ascender);
NSTextAttachment默认也是基线对齐,attachment.bounds的坐标原点Y轴是和基线持平,是coregraphics的坐标系。
如果将bounds高度设置为lineHeight,那么整个行高将会被拉大到lineHeight+decent的高度
NSTextAttachment.bounds = CGRectMake(0,0,[UIFont systemFontOfSize:30].lineHeight,[UIFont systemFontOfSize:30].lineHeight);
如果希望NSTextAttachment基线对齐
attachment.bounds = CGRectMake(0,0,[UIFont systemFontOfSize:30].ascender,[UIFont systemFontOfSize:30].ascender);
如果希望NSTextAttachment底部对齐
将bound.origin.y移动descender距离即可。
attachment.bounds = CGRectMake(0,[UIFont systemFontOfSize:30].descender,[UIFont systemFontOfSize:30].lineHeight,[UIFont systemFontOfSize:30].lineHeight);