问题描述
因此,SwiftUI为我们提供了一个不错的 .font()
扩展名,该扩展名使我们可以设置文本的字体大小,样式,粗细等.这很好地反映了CSS的字体属性,甚至还附带了类似 .font(.title)
, .font(.body)
, .font(.caption)
.
So SwiftUI gives us a nice .font()
extension that lets us set the font size, style, weight, etc. of text. This mirrors CSS's font attributes nicely, and even comes with nice shorthands like .font(.title)
, .font(.body)
, .font(.caption)
.
关于自定义字体,CSS很有意思,它使我们能够从一个或多个文件中导入字体,这些文件共同定义了同一系列中的几种粗细和样式.然后,您可以在文档的顶层声明一个字体系列,从而在所有地方自动使用该字体,然后所有字体声明将自动使用该字体.
CSS shines when it comes to custom fonts, allowing us to import font faces from one or more files that collectively define several weights and styles within the same family. You can then use that font everywhere automatically by declaring a font family at the top level of the document, and then all font declarations will use that font automatically.
iOS允许我们导入自定义字体,但是在使用时似乎不够.我正在寻找iOS反映CSS行为的方法.
iOS allows us to import custom fonts, but it seems to fall short when it comes to using them. I'm looking for a way for iOS to mirror CSS's behavior.
对于一个字体家族,我有10个字体文件:5种不同的粗细(轻,常规,半粗体,粗体和超粗体),每个均具有常规和斜体样式.我可以实例化这些字体的 UIFont
s,但是我正在寻找一种在全局范围内设置此字体系列的方法,以便可以声明 .font(.title,weight:.bold)
,并隐式使用字体大小为 title
的字体系列的粗体.
I have 10 font files for a single font family: 5 different weights (light, regular, semi-bold, bold, and extra-bold) each with a regular and italic style. I am able to instantiate UIFont
s for these fonts, but I'm looking for a way to set this font family globally so that I can declare .font(.title, weight: .bold)
and have it implicitly use my font family's bold variant with the title
size.
我知道可以全局替代字体的方法,但是我特别在寻找一种使用同一家族的多种字体来具有自动加粗和斜体功能的方法.如果有一种很好的SwiftUI方式可以做到这一点,那将是首选,但是UIKit解决方案也可以.
I am aware of ways to globally override the font, but I am specifically looking for a way to use multiple fonts from the same family to have automatic bold and italic capabilities. If there is a nice SwiftUI way to do this, that would be preferred, but a UIKit solution is fine as well.
我应该提到的另一件事是,即使没有 .font()
修饰符,我也希望每个 View
的默认字体都可以使用我的字体.所以如果我有
Another thing I should have mentioned is that I would like the default font of every View
to use my font even with no .font()
modifier. So if I have
Text("Hello, world")
它应该使用默认字体的字体和大小(我认为这是 .body
).
it should use my font with the default weight and size (I think this is .body
).
推荐答案
您可以开始定义自定义 ViewModifier
,以处理选择正确的字体和大小的逻辑:
You can start be defining a custom ViewModifier
to handle the logic of choosing the right type and size of a font:
struct MyFont: ViewModifier {
@Environment(\.sizeCategory) var sizeCategory
public enum TextStyle {
case title
case body
case price
}
var textStyle: TextStyle
func body(content: Content) -> some View {
let scaledSize = UIFontMetrics.default.scaledValue(for: size)
return content.font(.custom(fontName, size: scaledSize))
}
private var fontName: String {
switch textStyle {
case .title:
return "TitleFont-oBld"
case .body:
return "MyCustomFont-Regular"
case .price:
return "MyCustomFont-Mono"
}
}
private var size: CGFloat {
switch textStyle {
case .title:
return 26
case .body:
return 16
case .price:
return 14
}
}
}
在其中,您可以为要在应用程序中重复使用的所有文本样式定义一个枚举.您可以使用与本机 Font.TextStyle
相同的名称,例如 .title
, .body
,也可以定义自己的名称,例如 .price
在上面的示例中.
Inside it you define an enum for all the text styles you would like to reuse across your app. You can use the same names as native Font.TextStyle
such as .title
, .body
or define your own such as .price
in the example above.
对于每种 TextStyle
情况,都必须声明字体名称及其默认大小.如果在我的示例中包含 sizeCategory
,则字体将适应动态类型.
For each case of TextStyle
you have to declare the name of the font and its default size.If you include sizeCategory
as in my example the font would adapt for dynamic type.
您还可以在 View
上定义扩展名,以能够以与本机 font(_ font:Font?)
相同的方式应用此修饰符.
You can also define an extension on View
to be able to apply this modifier in the same way as the native font(_ font: Font?)
.
extension View {
func myFont(_ textStyle: MyFont.TextStyle) -> some View {
self.modifier(MyFont(textStyle: textStyle))
}
}
现在您可以像这样应用它:
Now you can apply it like this:
Text("Any text will do").myFont(.title)
Text("£3.99").myFont(.price)
对于没有应用修饰符的默认 Text
,您可以使用Mahdi BM的解决方案,也可以定义自己的类型:
For the default Text
without a modifier applied you could either use Mahdi BM's solution or define your own type:
struct MyText: View {
let text: String
init(_ text: String) {
self.text = text
}
var body: some View {
Text(text).myFont(.body)
}
}
这篇关于SwiftUI-使用多种样式覆盖系统字体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!