I'm working on an iOS project using Swift, and I'm trying to ensure that the font size in both UILabel
and UIButton
automatically scales down when the text doesn't fit. However, despite setting adjustsFontSizeToFitWidth
and minimumScaleFactor
, the font size doesn't seem to change at all.
struct UIStyling {
static func styleLabel(label: UILabel, textLabel: String) {
let fontName = "Montserrat-Medium"
let fontSize: CGFloat = 18
let minimumFontSize: CGFloat = 6
guard let font = UIFont(name: fontName, size: fontSize) else {
fatalError("Failed to load font \(fontName).")
}
let kernValue = fontSize * 0.2
let textColor = UIColor(hex: "FFFFFF")
label.numberOfLines = 0
label.textAlignment = .center
label.lineBreakMode = .byWordWrapping
label.adjustsFontSizeToFitWidth = true
label.minimumScaleFactor = minimumFontSize / fontSize
let labelAttributedString = NSMutableAttributedString(
string: textLabel,
attributes: [
.font: font,
.kern: kernValue,
.foregroundColor: textColor
]
)
label.attributedText = labelAttributedString
}
static func styleButton(
_ button: UIButton,
title: String,
fontName: String = "Montserrat-Medium",
fontSize: CGFloat = 18,
minimumFontSize: CGFloat = 6,
cornerRadius: CGFloat = 20,
backgroundColor: UIColor,
titleColor: UIColor
) {
guard let font = UIFont(name: fontName, size: fontSize) else {
fatalError("Failed to load font \(fontName).")
}
button.titleLabel?.adjustsFontSizeToFitWidth = true
button.titleLabel?.minimumScaleFactor = minimumFontSize / fontSize
button.titleLabel?.numberOfLines = 0
button.titleLabel?.lineBreakMode = .byClipping
button.setTitle(title, for: .normal)
button.titleLabel?.font = font
button.setTitleColor(titleColor, for: .normal)
button.backgroundColor = backgroundColor
button.layer.cornerRadius = cornerRadius
}
}
func buttonStyles(for sceneType: SceneType) -> (fontName: String, backgroundColors: [(UIColor, UIColor)], textColors: (UIColor, UIColor)) {
switch sceneType {
case .egypt:
return (
fontName: "Montserrat-Medium",
backgroundColors: [
(UIColor(hex: "#FFD700").withAlphaComponent(0.8), UIColor(hex: "#333333")),
(UIColor(hex: "#006400").withAlphaComponent(0.8), UIColor(hex: "#FFFFFF"))
],
textColors: (UIColor(hex: "#333333"), UIColor(hex: "#FFFFFF"))
)
case .future:
return (
fontName: "Montserrat-Medium",
backgroundColors: [
(UIColor(hex: "#1E90FF").withAlphaComponent(0.8), UIColor(hex: "#FFFFFF")),
(UIColor(hex: "#D3D0D0").withAlphaComponent(0.8), UIColor(hex: "#090909"))
],
textColors: (UIColor(hex: "#FFFFFF"), UIColor(hex: "#090909"))
)
case .main:
return (
fontName: "Montserrat-Medium",
backgroundColors: [
(UIColor(hex: "#FFD700").withAlphaComponent(0.8), UIColor(hex: "#333333")),
(UIColor(hex: "#1E90FF").withAlphaComponent(0.8), UIColor(hex: "#FFFFFF"))
],
textColors: (UIColor(hex: "#333333"), UIColor(hex: "#FFFFFF"))
)
}
}
func updateUI() {
let currentScene = storyBrain.getCurrentScene()
UIStyling.styleLabel(label: textLabel, textLabel: currentScene.title)
let styles = buttonStyles(for: currentScene.sceneType)
UIStyling.styleButton(button1,
title: currentScene.button1,
fontName: styles.fontName,
backgroundColor: styles.backgroundColors[0].0,
titleColor: styles.textColors.0)
UIStyling.styleButton(button2,
title: currentScene.button2,
fontName: styles.fontName,
backgroundColor: styles.backgroundColors[1].0,
titleColor: styles.textColors.1)
button1.layer.cornerRadius = Style.cornerRadius
button2.layer.cornerRadius = Style.cornerRadius
background.image = UIImage(named: currentScene.backgroundImage)
print("Label size: \(textLabel.frame.size)")
print("Minimum scale factor: \(textLabel.minimumScaleFactor)")
print("Font size: \(textLabel.font.pointSize)")
}
func updateUI() {
let currentScene = storyBrain.getCurrentScene()
UIStyling.styleLabel(label: textLabel, textLabel: currentScene.title)
let styles = buttonStyles(for: currentScene.sceneType)
UIStyling.styleButton(button1,
title: currentScene.button1,
fontName: styles.fontName,
backgroundColor: styles.backgroundColors[0].0,
titleColor: styles.textColors.0)
UIStyling.styleButton(button2,
title: currentScene.button2,
fontName: styles.fontName,
backgroundColor: styles.backgroundColors[1].0,
titleColor: styles.textColors.1)
button1.layer.cornerRadius = Style.cornerRadius
button2.layer.cornerRadius = Style.cornerRadius
background.image = UIImage(named: currentScene.backgroundImage)
print("Label size: \(textLabel.frame.size)")
print("Minimum scale factor: \(textLabel.minimumScaleFactor)")
print("Font size: \(textLabel.font.pointSize)")
// ...
}
Problem Description:
UILabel
and UIButton
does not change, even if the text is too long to fit.minimumScaleFactor
setting.adjustsFontSizeToFitWidth
and minimumScaleFactor
properties.What I've Tried:
adjustsFontSizeToFitWidth
and minimumScaleFactor
programmatically: As shown in the code above, I've set these properties, but the font size does not scale down.minimumFontSize
values: I tried different values for the minimumFontSize
, but it didn't make any difference.Questions:
minimumScaleFactor
being ignored? Is there something in my code that could be preventing this from working?Environment:
To get auto-font-scaling, .lineBreakMode
has to be set to clipping or one of the truncating modes - Head, Middle, or (most commonly) Tail:
//label.lineBreakMode = .byWordWrapping
label.lineBreakMode = .byTruncatingTail