美文网首页
iOS 富文本高度计算,字符串\n高度计算。

iOS 富文本高度计算,字符串\n高度计算。

作者: follow_er | 来源:发表于2021-06-07 16:30 被阅读0次

问题:服务器返回一段文字带有折行\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;
}

相关文章

网友评论

      本文标题:iOS 富文本高度计算,字符串\n高度计算。

      本文链接:https://www.haomeiwen.com/subject/bftfeltx.html