web-dev-qa-db-ja.com

SKLabelNodeのフォントサイズを固定サイズに合わせて設定する方法(Swift)

SKLabelNodeが入った正方形(200X200)があります。ラベルにはスコアが表示されており、かなりの数に達する可能性があります。数字を四角に合わせたい。

SKLabelNodeのテキストサイズ(またはサイズ)を変更して、固定サイズに合わせるにはどうすればよいですか。

19
nmokkary

SKLabelNodeのフレームのサイズは、指定された長方形と比較できます。ラベルの長方形と目的の長方形のサイズに比例してフォントを拡大縮小すると、スペースを可能な限り埋めるのに最適なフォントサイズを決定できます。最後の行は、ラベルを長方形の中心に移動するのに便利です。 (テキストが小文字や句読点などの短い文字のみの場合、中心から外れて見える場合があります。)

スイフト

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);
}
30
mike663

私はこれを幅のために書きました、しかしあなたはあなたの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
Myoch

Mike663の答えのこの拡張は私にとってはうまくいき、一度に1ピクセル進むよりもはるかに速くそこに到達します。

// 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
0
DenverCoder9