问题:服务器返回一段文字带有折行\n,需要添加行间距对这段文字进行展示。
分析:富文本中带有\n计算高度时,系统会把\n当做字符串来计算,不会计算出行高和行间距。
下面是系统的方法
- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options context:(nullable NSStringDrawingContext *)context
封装调用的方法,发现高度返回不正确。
+ (CGSize)sizeOfAttributedString:(NSAttributedString *)str fittingSize:(CGSize)fittingSize {
CGRect rect = [str boundingRectWithSize:fittingSize options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:nil];
return CGSizeMake(ceil(rect.size.width), ceil(rect.size.height)); //进位取整, 防止文字内带字母计算太极端问题
}
解决方式: 采用string计算的方法,系统会计算\n的高度
- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(nullable NSDictionary<NSAttributedStringKey, id> *)attributes context:(nullable NSStringDrawingContext *)context
其中attributes需要传入富文本设置的行高,所以,我们还需要遍历拿到的富文本,传值。
- (void)enumerateAttributesInRange:(NSRange)enumerationRange options:(NSAttributedStringEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(NSDictionary<NSAttributedStringKey, id> *attrs, NSRange range, BOOL *stop))block
下面是demo示例代码
- (void)viewDidLoad {
[super viewDidLoad];
UILabel *labText = [[UILabel alloc] init];
labText.numberOfLines = 0;
NSString *strPackagePrice = @"4800元";
NSMutableAttributedString *attriPackagePrice = [[NSMutableAttributedString alloc] initWithString:strPackagePrice];
NSRange rangePackagePrice = [strPackagePrice rangeOfString:@"元"];
[attriPackagePrice addAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:14]} range:rangePackagePrice];
// 套餐包价格 < 原价
NSString *ori_priceUnitTitleStr = [NSString stringWithFormat:@"\n原价:9600元/月"];
NSMutableAttributedString *attriOriginalPrice = [[NSMutableAttributedString alloc] initWithString:ori_priceUnitTitleStr];
[attriOriginalPrice addAttributes:@{
NSFontAttributeName : [UIFont systemFontOfSize:12],
NSForegroundColorAttributeName : [UIColor redColor] }
range:NSMakeRange(0, ori_priceUnitTitleStr.length)];
//添加下划线
NSRange rangeUnderLine = [ori_priceUnitTitleStr rangeOfString:@"9600元/月"];
[attriOriginalPrice addAttributes:@{NSStrikethroughStyleAttributeName : [NSNumber numberWithInteger:NSUnderlineStyleSingle]} range:rangeUnderLine];
NSMutableParagraphStyle *paragraphStyle2 = [[NSMutableParagraphStyle alloc] init];
paragraphStyle2.lineSpacing = 10; // 调整行间距
paragraphStyle2.lineBreakMode = NSLineBreakByCharWrapping;
[attriOriginalPrice addAttribute:NSParagraphStyleAttributeName value:paragraphStyle2 range:NSMakeRange(0, attriOriginalPrice.length)];
[attriPackagePrice appendAttributedString:attriOriginalPrice];
labText.attributedText = attriPackagePrice;
CGFloat labPriceH = ceil([attriPackagePrice boundingRectWithSize:CGSizeMake(300, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin context:nil].size.height);
NSLog(@"labPriceH: %.2lf", labPriceH);
NSRange range = NSMakeRange(0, attriPackagePrice.string.length);
NSMutableDictionary *dictAttributes = [NSMutableDictionary dictionary];
[labText.attributedText enumerateAttributesInRange:range options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:^(NSDictionary<NSAttributedStringKey,id> * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) {
[dictAttributes addEntriesFromDictionary:attrs];
}];
CGSize size1 = [attriPackagePrice.string sizeWithAttributes:dictAttributes];
NSLog(@"size1:%@", NSStringFromCGSize(size1));
CGSize size2 = [attriPackagePrice.string boundingRectWithSize:CGSizeMake(300, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:dictAttributes context:nil].size;
NSLog(@"size2:%@", NSStringFromCGSize(size2));
CGFloat labPriceSizeH = size2.height;
labText.frame = CGRectMake(50, 300, 300, labPriceSizeH);
[self.view addSubview:labText];
labText.layer.borderColor = [UIColor redColor].CGColor;
labText.layer.borderWidth = 2;
}
网友评论