Как установить размер шрифта SKLabelNode для фиксированного размера (Swift)
У меня есть квадрат (200X200) с SKLabelNode
в нем. На этикетке отображается оценка, и я получаю большое количество. Я хочу соответствовать номеру на площади.
Как я могу изменить размер текста (или размер) SKLabelNode
, чтобы соответствовать ему в фиксированном размере.
Ответы
Ответ 1
Размер рамки 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);
}
Ответ 2
Я написал это для ширины, но вы можете приспособить его к высоте, чтобы соответствовать вашему 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
}
Ответ 3
Это расширение ответа 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