【问题标题】:CATextlayer change size of FONT to fit the frameCATextlayer 更改 FONT 的大小以适合框架
【发布时间】:2019-05-23 23:31:06
【问题描述】:

我有一个特定大小的CATextlayer 和未知长度的NSAttributedString 文本。

我需要调整字体大小以使文本适合框架(反之亦然:)

任何想法从哪里开始? :)

[编辑]正如nall指出的,我可以确定字符串的长度,当然,我需要将用户输入的一些文本放入一个固定大小的盒子中。

【问题讨论】:

  • 当你说'未知长度的文本'时,你的意思是在编译时不知道吗?在某些时候,您必须知道长度...
  • 哈哈-好的,好点。它是用户在某个时候输入的文本。当然,我可以得到字符串长度... :)

标签: ios xcode catextlayer


【解决方案1】:

Swift 5 清洁解决方案工作。

1) 扩展字符串

extension String {
    func size(OfFont font: UIFont) -> CGSize {
        return (self as NSString).size(withAttributes: [NSAttributedString.Key.font: font])
    }
}

2) 继承 CATextLayer

class DynamicTextLayer : CATextLayer {
    var adjustsFontSizeToFitWidth = false

    override func layoutSublayers() {
        super.layoutSublayers()
        if adjustsFontSizeToFitWidth {
            fitToFrame()
        }
    }

    func fitToFrame(){
        // Calculates the string size.
        var stringSize: CGSize  {
            get { return (string as? String)!.size(OfFont: UIFont(name: (font as! UIFont).fontName, size: fontSize)!) }
        }
        // Adds inset from the borders. Optional
        let inset: CGFloat = 2
        // Decreases the font size until criteria met
        while frame.width < stringSize.width + inset {
            fontSize -= 1
        }
    }
}

3) 现在转到您的代码,而不是 CATextLayer 使用 DynamicTextLayer

textLayer = DynamicTextLayer()
textLayer?.alignmentMode = .center
textLayer?.fontSize = 40
textLayer?.string = "Example"
textLayer?.adjustsFontSizeToFitWidth = true

【讨论】:

  • 对我来说,我得到了额外的高度,宽度是完美的
  • @Nick 你可以像这样let textLayer = CATextLayer() textLayer.font?.lineHeight
  • 但我想在创建 CATextLayer 之前设置高度。我正在用 cgrect 初始化框架
  • 如果您知道要使用的字体,则可以在制作文本图层之前计算高度。 let font = UIFont()font.lineHeight
【解决方案2】:

我通过这样做实现了它:

    float fontSize = InitialFontSize;
    UIFont *myFont = [UIFont boldSystemFontOfSize:fontSize];
    CGSize myFontSize = [YourTextHere sizeWithFont:myFont];
    while (myFontSize.width >= MaximunWidth) {
        fontSize -= 0.1f;
        myFont = [UIFont boldSystemFontOfSize:fontSize];
        myFontSize = [YourTextHere sizeWithFont:myFont];
    }
    CATextLayer *textLayer = [CATextLayer layer];
    [textLayer setFrame:CGRectMake(MaximunWidth - myFontSize.width / 2, MaximunHeight - myFontSize.height / 2, myFontSize.width, myFontSize.height)];
    [textLayer setFontSize:fontSize];
    [textLayer setString:YourTextHere];

    [textLayer setAlignmentMode:kCAAlignmentCenter];

【讨论】:

  • “MaximunWidth”是 CALayerWidth 框架吗?
  • @OfirMalachi 不,是文本大小不能超过的固定大小
【解决方案3】:

我最终这样做了:

textlayerCATextlayer

theStringNSMutableAttributedString

是的,它不是很优雅,绝对可以改进;)

CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)theString);

    CGRect columnRect = CGRectMake(0, 0 , 320, 150);

    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddRect(path, NULL, columnRect);

    CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);

    CFRange frameRange = CTFrameGetVisibleStringRange(frame); 

    int fontSize = 18;

    while(theString.string.length > frameRange.length){

        fontSize--;

        CFStringRef fontName = (__bridge CFStringRef)[defs objectForKey:@"font"];

        CTFontRef font = CTFontCreateWithName(fontName, fontSize, NULL);

        [theString addAttribute:(NSString *)kCTFontAttributeName
                          value:(__bridge id)font
                          range:NSMakeRange(0, theString.string.length)];

        CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)theString);

        CGRect columnRect = CGRectMake(0, 0 , 320, 150);

        CGMutablePathRef path = CGPathCreateMutable();
        CGPathAddRect(path, NULL, columnRect);

        CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);

        frameRange = CTFrameGetVisibleStringRange(frame); 

        textLayer.string = theString;
    }

【讨论】:

  • “defs”是什么意思?
【解决方案4】:
CATextLayer *textLayer;

[textLayer setWrapped: TRUE];

希望这会奏效

【讨论】:

  • 哇 - 这看起来很短...... ;) 我会试一试!谢谢!
猜你喜欢
  • 2012-05-05
  • 1970-01-01
  • 1970-01-01
  • 2015-06-16
  • 1970-01-01
  • 2011-04-06
  • 1970-01-01
  • 2014-03-05
  • 1970-01-01
相关资源
最近更新 更多