Я работаю над проектом iOS с использованием Swift и пытаюсь обеспечить, чтобы размер шрифта как в UILabel
, так и в UIButton
автоматически уменьшался, когда текст не помещался. Однако, несмотря на установку adjustsFontSizeToFitWidth
и minimumScaleFactor
, размер шрифта, похоже, вообще не меняется.
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)")
// ...
}
Описание проблемы:
UILabel
, так и в UIButton
не меняется, даже если текст слишком длинный и не помещается.minimumScaleFactor
.adjustsFontSizeToFitWidth
и minimumScaleFactor
.Что я пробовал:
adjustsFontSizeToFitWidth
и minimumScaleFactor
: как показано в приведенном выше коде, я установил эти свойства, но размер шрифта не уменьшается.minimumFontSize
: я пробовал разные значения minimumFontSize
, но это не имело никакого значения.Вопросы:
minimumScaleFactor
игнорируется? Есть ли что-то в моем коде, что может помешать этому работать?Среда:
Обычно шрифт не масштабируется с помощью NSAttributedString
(или связанных с ним свойств attributedText
).
Чтобы получить автоматическое масштабирование шрифта, .lineBreakMode
должен быть установлен на отсечение или один из режимов усечения — Head, Middle или (чаще всего) Tail:
//label.lineBreakMode = .byWordWrapping
label.lineBreakMode = .byTruncatingTail
Спасибо за помощь! Проблема действительно была в lineBreakMode. После изменения label.lineBreakMode = .byWordWrapping на label.lineBreakMode = .byTruncatingTail автоматическое масштабирование шрифтов начало работать правильно. Теперь все работает отлично. Еще раз спасибо за дельный совет!
Пожалуйста, покажите минимальный воспроизводимый пример - некоторый код, который я могу вставить в новый проект и воспроизвести проблему.