如何将SKLabelNode的字体大小设置为适合固定尺寸(Swift)

21

我有一个 200x200 的正方形,里面有一个 SKLabelNode。标签显示得分,可能会达到一个很大的数字。我想把数字适应到这个正方形中。

如何更改SKLabelNode的文本大小(或大小),以适应固定大小。

3个回答

33

可以将SKLabelNode的框架大小与给定的矩形进行比较。如果根据标签矩形和所需矩形的大小比例缩放字体,就可以确定填充空间的最佳字体大小。最后一行方便地将标签移动到矩形的中心。(如果文本只包含小写字母或标点符号等短字符,则可能看起来不居中。)

Swift

func adjustLabelFontSizeToFitRect(labelNode:SKLabelNode, rect:CGRect) {

    // Determine the font scaling factor that should let the label text fit in the given rectangle.
    let scalingFactor = min(rect.width / labelNode.frame.width, rect.height / labelNode.frame.height)

    // Change the fontSize.
    labelNode.fontSize *= scalingFactor

    // Optionally move the SKLabelNode to the center of the rectangle.
    labelNode.position = CGPoint(x: rect.midX, y: rect.midY - labelNode.frame.height / 2.0)
}

Objective-C

-(void)adjustLabelFontSizeToFitRect:(SKLabelNode*)labelNode rect:(CGRect)rect {

    // Determine the font scaling factor that should let the label text fit in the given rectangle.
    double scalingFactor = MIN(rect.size.width / labelNode.frame.size.width, rect.size.height / labelNode.frame.size.height);

    // Change the fontSize.
    labelNode.fontSize *= scalingFactor;

    // Optionally move the SKLabelNode to the center of the rectangle.
    labelNode.position = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect) - labelNode.frame.size.height / 2.0);
}

1
请注意,在标签节点和矩形之间可能需要额外的填充。MIN(rect.size.width / (labelNode.frame.size.width + PADDING), rect.size.height / (labelNode.frame.size.height + PADDING)); - Wouter
这在2019年对我不起作用,我的字体(Menlo-Bold with emojis!)的fontSize显然与所占空间不成比例,但我已经将该scalingFactor用于下面的解决方案 :) - DenverCoder9
Menlo是一种固定宽度字体。你在2019年尝试过等宽字体吗? - mike663

3
我已经为宽度编写了这个内容,但您可以根据需要将其适应到高度以适合您的CGRect。在示例中,pg是使用您正在使用的字体初始化的SKLabelNode。参数是您的字符串和目标宽度,结果是要分配给SKLabelNode的大小。当然,您也可以直接放置SKLabelNode。如果大小太大,则最大大小为50,但这是个人喜好。
 func getTextSizeFromWidth(s:String, w:CGFloat)->CGFloat {

    var result:CGFloat = 0;
    var fits:Bool = false
    pg!.text=s
    if(s != ""){
      while (!fits) {
        result++;
        pg!.fontSize=result
        fits = pg!.frame.size.width > w;
      }
    result -= 1.0
    }else{
        result=0;
    }

    return min(result, CGFloat(50))
}

编辑:实际上,我刚刚意识到我也写了这个:

extension SKLabelNode {
func fitToWidth(maxWidth:CGFloat){
    while frame.size.width >= maxWidth {
        fontSize-=1.0
    }
}

func fitToHeight(maxHeight:CGFloat){
    while frame.size.height >= maxHeight {
        fontSize-=1.0
    }

-1
这个mike663的回答的扩展对我很有帮助,比一次移动一个像素快得多。
// Find the right size by trial & error...
var testingSize: CGFloat = 0    // start from here
var currentStep: CGFloat = 16   // go up by this much. It will be reduced each time we overshoot.
var foundMatch = false

while !foundMatch {
    var overShot = false
    while !overShot {
        testingSize += currentStep
        labelNode.fontSize = testingSize
        // How much bigger the text should be to perfectly fit in the given rectangle.
        let scalingFactor = min(rect.width / labelNode.frame.width, rect.height / labelNode.frame.height)

        if scalingFactor < 1         { overShot   = true }  // Never go over the space
        else if scalingFactor < 1.01 { foundMatch = true }  // Stop when over 99% of the space is filled
    }
    testingSize -= currentStep  // go back to the last one that didn't overshoot
    currentStep /= 4
}
labelNode.fontSize = testingSize // go back to the one we were happy with

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接