Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set font size of SKLabelNode to fit in fixed size (Swift)

I have a square (200X200) with a SKLabelNode in it. The label shows score and it my be reach a large number. I want fit the number in the square.

How can i change text size (or Size) of a SKLabelNode to fit it in a fixed size.

like image 530
nmokkary Avatar asked Jun 22 '15 13:06

nmokkary


2 Answers

The size of the frame of the SKLabelNode can be compared against the given rectangle. If you scale the font in proportion to the sizes of the label's rectangle and the desired rectangle, you can determine the best font size to fill the space as much as possible. The last line conveniently moves the label to the center of the rectangle. (It may look off-center if the text is only short characters like lowercase letters or punctuation.)

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); } 
like image 74
mike663 Avatar answered Sep 30 '22 21:09

mike663


I have written this for the width, but you can adapt it to the height to fit your CGRect. In the example, pg is a SKLabelNode initialized with the font you are using. Arguments are your String and the target width, and the result is the size you want to assign to your SKLabelNode. Of course, you can also put directly your SKLabelNode. If the size is too big, then the max size is 50, but that's personal.

 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))
}

Edit: Actually, I just realized I had also written this:

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
    }
like image 30
Myoch Avatar answered Sep 30 '22 19:09

Myoch