Как установить размер шрифта SKLabelNode, чтобы соответствовать фиксированному размеру (Swift)

У меня есть квадрат (200X200) с SKLabelNode в этом. Метка показывает счет, и это может быть большое количество. Я хочу вписать число в квадрат.

Как я могу изменить размер текста (или размер) SKLabelNode чтобы соответствовать ему в фиксированном размере.

2 ответа

Размер кадра 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);
}

Я написал это для ширины, но вы можете адаптировать его к высоте, чтобы соответствовать вашему 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
    }

Это расширение ответа 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
Другие вопросы по тегам