我在我的应用程序中使用TextStyles
来支持动态字体。我有挑战改变每个TextStyle
的字体。因此,例如TextStyle.body
应该是MyAwesomeBODYFont,而TextStyle.headline
应该是MyAwesomeHeadlineFont。这适用于整个应用程序。设置整个应用程序的字体不起作用,因为我需要几个不同样式的字体。
是否可以使用自定义字体以某种方式覆盖这些TextStyles
整个应用程序,而不是分别为每个标签?
我尝试了什么:
设置appearance
的UILabel
代理的字体通常可以正常工作:
let labelAppearance = UILabel.appearance()
let fontMetrics = UIFontMetrics(forTextStyle: .body)
labelAppearance.font = fontMetrics.scaledFont(for: myAwesomeBodyFont)
但这会覆盖所有标签,无论他们使用什么TextStyle
都无关紧要。
之后我尝试检查TextStyle
,但它崩溃了UILabel.appearance()。字体的nil指针异常或者甚至没有进入if-block。
let labelAppearance = UILabel.appearance()
if let textStyle = labelAppearance.font.fontDescriptor.object(forKey: UIFontDescriptor.AttributeName.textStyle) as? UIFont.TextStyle {
// this would be the place to check for the TextStyle and use the corresponding font
let fontMetrics = UIFontMetrics(forTextStyle: textStyle)
labelAppearance.font = fontMetrics.scaledFont(for: mayAwesomeBodyFont)
}
因为UILabel的外观没有设置font
。
您不能直接“设置”文本样式的自定义字体。您可以获得文本样式的字体大小,然后可以使用自定义系列。
let systemDynamicFontDescriptor = UIFontDescriptor.preferredFontDescriptorWithTextStyle(UIFontTextStyleBody)
let size = systemDynamicFontDescriptor.pointSize
let font = UIFont(name: MyAwesomeBODYFont, size: size)
对于iOS 11+,有scaledFont()
你可以使这个字体变量静态,并可以在应用程序的任何地方使用它。
您也可以查看这个解决方案:https://stackoverflow.com/a/42235227/4846167
我最终创建了UILabel的子类,让我的所有标签都从它继承。这样您就可以在InterfaceBuilder中设置类和/或在代码中创建自定义类。
这是DynamicCustomFontLabel类:
import UIKit
class DynamicCustomFontLabel: UILabel {
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
initCustomFont()
}
override init(frame: CGRect) {
super.init(frame: frame)
initCustomFont()
}
private func initCustomFont() {
if let textStyle = font.fontDescriptor.object(forKey: UIFontDescriptor.AttributeName.textStyle) as? UIFont.TextStyle {
let fontMetrics = UIFontMetrics(forTextStyle: textStyle)
var customFont: UIFont?
switch textStyle {
case .body:
customFont = UIFont(name: "MyAwesomeBODYFont", size: 21)
case .headline:
customFont = UIFont(name: "MyAwesomeHeadlineFont", size: 48)
// all other cases...
default:
return
}
guard let font = customFont else {
fatalError("Failed to load a custom font! Make sure the font file is included in the project and the font is added to the Info.plist.")
}
self.font = fontMetrics.scaledFont(for: font)
}
}
}