iOS 9设置firstLineHeadIndent后数字消失,iOS 11显示正常
iOS 9下设置
firstLineHeadIndent导致数字消失的问题排查与解决 我之前在适配iOS9的时候也碰到过一模一样的问题,折腾了好一会儿才找到根源,给你梳理下:
问题到底出在哪?
这是iOS 9系统NSParagraphStyle的一个排版渲染bug:当你设置的firstLineHeadIndent值大于等于文本内容的实际宽度时,对于以数字开头的文本,系统会错误地判定数字部分已经超出了标签的可视区域,直接把这部分内容“吃掉”不渲染了。你这里用self.titleLabel.frame.size.width + 4作为缩进值,大概率已经超过了descLabel里数字开头文本的宽度,刚好触发了这个iOS9特有的坑。
几个可行的解决办法
1. 给缩进值加个安全上限,别让内容完全偏移出去
不要直接把titleLabel的宽度加4直接用,而是根据descLabel的可用宽度做个限制,确保缩进后首行还有内容能显示在可视区域里:
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc]init]; // 先算出descLabel实际能显示内容的宽度,减去内边距 CGFloat availableWidth = CGRectGetWidth(self.descLabel.bounds) - self.descLabel.layoutMargins.left - self.descLabel.layoutMargins.right; // 确保缩进值小于可用宽度,留10pt的安全空间避免内容被挤没 style.firstLineHeadIndent = MIN(self.titleLabel.frame.size.width + 4, availableWidth - 10); NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:self.descLabel.text]; [attrString addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0, self.descLabel.text.length)]; self.descLabel.attributedText = attrString;
2. 用空格缩进替代首行属性(iOS9兜底方案)
如果动态计算还是有问题,可以换个思路,直接在文本开头加对应宽度的空格,代替firstLineHeadIndent的设置:
// 根据字体大小换算需要多少个空格才能达到目标缩进宽度 CGFloat indentWidth = self.titleLabel.frame.size.width + 4; CGFloat singleSpaceWidth = [@" " sizeWithAttributes:@{NSFontAttributeName: self.descLabel.font}].width; NSInteger spaceCount = ceil(indentWidth / singleSpaceWidth); NSString *prefixSpaces = [@"" stringByPaddingToLength:spaceCount withString:@" " startingAtIndex:0]; NSString *newText = [NSString stringWithFormat:@"%@%@", prefixSpaces, self.descLabel.text]; self.descLabel.text = newText;
3. 针对iOS9做版本适配,避开bug
只在iOS10及以上系统使用firstLineHeadIndent,iOS9用兼容方案:
if (@available(iOS 10.0, *)) { // 高版本正常用首行缩进 NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc]init]; style.firstLineHeadIndent = self.titleLabel.frame.size.width + 4; NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:self.descLabel.text]; [attrString addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0, self.descLabel.text.length)]; self.descLabel.attributedText = attrString; } else { // iOS9用空格缩进替代 CGFloat indentWidth = self.titleLabel.frame.size.width + 4; CGFloat singleSpaceWidth = [@" " sizeWithAttributes:@{NSFontAttributeName: self.descLabel.font}].width; NSInteger spaceCount = ceil(indentWidth / singleSpaceWidth); NSString *prefixSpaces = [@"" stringByPaddingToLength:spaceCount withString:@" " startingAtIndex:0]; self.descLabel.text = [NSString stringWithFormat:@"%@%@", prefixSpaces, self.descLabel.text]; }
小建议
你可以先试试第一个方案,给缩进值加个上限,应该就能解决iOS9下数字消失的问题。如果还是有特殊场景不生效,再用版本适配的方案,彻底避开这个bug。
内容的提问来源于stack exchange,提问作者无夜之星辰
相关产品推荐
相关产品推荐

