SwiftUI-使用多种样式覆盖系统字体 [英] SwiftUI - Override the system font with multiple styles

查看:116
本文介绍了SwiftUI-使用多种样式覆盖系统字体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,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.

对于一个字体家族,我有1​​0个字体文件: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 UIFonts 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-使用多种样式覆盖系统字体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆