我正在玩SwiftUI,并且想为我的项目使用自定义UI字体。但是,我不想失去内置字体类(例如,大标题)附带的动态类型调整大小。

Apple确实为Text提供了自定义字体修饰符:

Text("Hello, world!")
    .font(.custom("Papyrus", size: 17))

但是,这会将大小固定为17pt。当您在设备上或模拟器中运行此命令并打开“辅助功能检查器”以调整操作系统级别的字体大小时,Text元素不会更新。
size:参数不是可选的,因此您必须传递一些内容。不幸的是,您无法获得现有字体(甚至是自定义字体)的size,因为Font没有size参数。

在SwiftUI的其余部分中,参数可以是可选的,或者您可以传入nil来显式禁用某些行为,这似乎是一种常见的模式。我希望size:上的.custom()参数是可选的,并且在内部使用以前Font修饰符的大小,或者使用Text设置的默认大小。

另外,定义系统样式的静态方法(例如.largeTitle)可以接受提供自定义字体名称的参数:.largeTitle("Papyrus")
有人有解决方法吗?

最佳答案

我偶然发现了一种也可以通过ViewModifier实现此目的的好方法。我从this Hacking With Swift's article借用了有关动态类型和自定义字体的基本修饰符。结果如下:

import SwiftUI

@available(iOS 13, macCatalyst 13, tvOS 13, watchOS 6, *)
struct CustomFont: ViewModifier {
    @Environment(\.sizeCategory) var sizeCategory

    var name: String
    var style: UIFont.TextStyle
    var weight: Font.Weight = .regular

    func body(content: Content) -> some View {
        return content.font(Font.custom(
            name,
            size: UIFont.preferredFont(forTextStyle: style).pointSize)
            .weight(weight))
    }
}

@available(iOS 13, macCatalyst 13, tvOS 13, watchOS 6, *)
extension View {
    func customFont(
        name: String,
        style: UIFont.TextStyle,
        weight: Font.Weight = .regular) -> some View {
        return self.modifier(CustomFont(name: name, style: style, weight: weight))
    }
}

和用法:
Text("Hello World!")
    .customFont(name: "Georgia", style: .headline, weight: .bold)

这样,您可以坚持捆绑的文本样式,而无需显式提供大小。如果您想这样做,font修饰符已经允许我们这样做,并且可以通过为此问题提供的一种替代方法来处理缩放。

另外,请注意,由于样式是在符合ViewModifierstruct中应用的,而sizeCategory继而响应对环境ojit_code的更改,因此 View 将在切换回您的应用程序时立即反射(reflect)对可访问性设置的更改;因此无需重新启动它。

10-07 19:04
查看更多