富文本计算最适字体大小

需求就像UILabel上面的sizeToFit(),但是是直接画出来的,没有使用label,
所以自己写了一个计算最适字体大小的方法,保证视图完美容纳富文本

小数在屏幕上会有进位的问题,因此需要保证,计算出的宽度,一定要小于视图的大小,因此ceil了一个px的余量

代码如下:

/// 计算字符串对应的指定宽度的最适字体大小
/// - Parameters:
///   - str: 目标字符串
///   - size: 目标尺寸
///   - baseFont: 基于字体大小开始计算
/// - Returns: 字体的size
func calBestFitFont(str: String, size: CGSize, baseFont: UIFont) -> CGFloat {
    let tmpFont = baseFont.pointSize;

    let attrKeyValues: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.black, .font: baseFont];
    let attr = NSAttributedString(string: str, attributes: attrKeyValues)

    let calSize = attr.boundingRect(with: CGSize(width: CGFloat.greatestFiniteMagnitude, height: tmpFont * 1.5), options: NSStringDrawingOptions.usesLineFragmentOrigin, context: nil).size
    let width = ceil(calSize.width);
    print("中间数据 \(calSize.width)");
    if size.width - width < 1 , size.width - width >= 0{
        return tmpFont
    } else {
        return calBestFitFont(str: str, size: size, baseFont: UIFont.systemFont(ofSize: tmpFont * (size.width/width)))
    }
}

实际测试效果如下,基本保证使用3次计算即可达到合适大小,比一个字号一个字号的循环要好多了。

至于这里的width,为什么要ceil, 一个是误差在1px以内的时候,可以认为达到目标,二是因为,当数据算到小数点后好多位的时候,字体的size的比值已经很相近,导致无限循环,就像一碗水,每次取一半,那永远也取不完

中间数据 164.91975778341293
中间数据 55.42169744318181
中间数据 49.48365843141235
string:4s7gxSwcAUuVgKW-------------fontSize:4.870129870129871
中间数据 80.72781318426132
中间数据 52.64756944444444
中间数据 49.995086477987414
string:n4TGo9Yl-------------fontSize:10.482180293501049
中间数据 49.71966540813446
string:dQMg-------------fontSize:18.0
中间数据 318.7265405058861
中间数据 55.411044034090914
中间数据 49.47414645900973
string:fvQEnAmKW41HgMG2uesccwLVUfBQv-------------fontSize:2.5190326914464847
中间数据 204.88192015886307
中间数据 56.4064881859756
中间数据 49.47937560173298
string:bYo9F8tGlcTLqCTGijB0gf-------------fontSize:3.851091142490372
中间数据 29.534398913383484
中间数据 48.10546875
中间数据 49.04237085459184
string:JKx-------------fontSize:30.612244897959183
中间数据 234.21144711971283
中间数据 55.18409242021278
中间数据 49.271511089475695
string:QZQEwYU69wNpTdodLwBxq-------------fontSize:3.4194528875379944
中间数据 126.98018860816956
中间数据 55.01468688484253
中间数据 49.528072601764634
string:W0z5NP3BkTxr-------------fontSize:6.327334083239596
中间数据 272.7897495031357
中间数据 55.88781335851647
中间数据 49.899833355818295
string:ZwoR9ktNza1oO6oRl3b0cV2Rf3n-------------fontSize:2.9434850863422293
中间数据 11.6578808426857
中间数据 47.71728515625
中间数据 49.62921142578125
string:A-------------fontSize:78.125
中间数据 189.93099957704544
中间数据 55.345651726973685
中间数据 49.41576047051221
string:WyjCmRa1RsuWaEmCZ-------------fontSize:4.2293233082706765
中间数据 216.786294400692
中间数据 55.77004428283411
中间数据 49.794682395387596
string:h4KwwTiPtxO3O2evWx4rc-------------fontSize:3.70309414088216
中间数据 281.1776897907257
中间数据 55.80743018617021
中间数据 49.82806266622339
string:xjT6alXodf2wXfAMQlOm3jsd4AUD-------------fontSize:2.8495440729483286
中间数据 274.6182419657707
中间数据 55.61878551136364
中间数据 49.659629920860404
string:G4YEqUTLdaKIvfboUhxO3HmTgX-------------fontSize:2.9220779220779223
中间数据 67.288991689682
中间数据 51.015337775735304
中间数据 49.27691291360295
string:GgJ95G-------------fontSize:12.726244343891404
中间数据 40.56106263399124
中间数据 48.44740360248379
中间数据 49.40017397692098
string:z5xX-------------fontSize:22.399203583872573
中间数据 69.38357323408127
中间数据 51.22767857142857
中间数据 49.47469522664835
string:v3DVND-------------fontSize:12.362637362637363
中间数据 207.29972451925278
中间数据 55.32883864182692
中间数据 49.400748787345464
string:oMpoVkHYuvtSwu4QSDo-------------fontSize:3.8633241758241756
中间数据 226.44070726633072
中间数据 55.678904529185026
中间数据 49.713307615343766
string:9OGFOojCGNoFAEy0rCclgv-------------fontSize:3.539962240402769
中间数据 63.36066430807114
中间数据 50.8392333984375
中间数据 49.96355842141544
string:CBv2k5-------------fontSize:13.786764705882351
中间数据 233.3273132443428
中间数据 55.74669471153845
中间数据 49.77383456387362
string:Cbqp9lFCfaca4aHgOVBulU9-------------fontSize:3.434065934065934
中间数据 92.57904696464539
中间数据 53.66998487903225
中间数据 50.13195844534049
中间数据 49.277663574390324
string:XPhbp62lvi-------------fontSize:8.784875957551478
中间数据 234.39156979322433
中间数据 55.74696642287235
中间数据 49.774077163278875
string:bAEnzVpXlAB87xqHqkyhtoW-------------fontSize:3.4194528875379944
中间数据 280.830139875412
中间数据 55.9356580849644
中间数据 49.942551861575375
string:q5hAtiX0luvOMabIAN0UFnbyN81d-------------fontSize:2.859684799186579

你可能感兴趣的:(富文本计算最适字体大小)