swift - 是否可以在 SwiftUI 中使用带有自定义字体的动态字体大小?

标签 swift user-interface fonts swiftui

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

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

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

但是,这会将大小固定为 17pt。当您在设备或模拟器中运行它并打开辅助功能检查器以调整操作系统级别的字体大小时,Text 元素不会更新。

size: 参数不是可选的,因此您必须传入一些内容。不幸的是,您无法获得现有字体(即使是自定义字体)的 size,因为 Font 没有 size 参数.

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

或者,定义系统样式的静态方法(例如 .largeTitle)可以接受提供自定义字体名称的参数:.largeTitle("Papyrus")

有没有人有解决方法?

最佳答案

我的方法是创建一个可以绑定(bind)到环境大小类别变化的自定义修饰符:

每当你需要使用 Papyrus 时,你会像这样使用它:

Text("Hello World!").modifier(Papyrus())

或者像这样:

Text("Hello World!").modifier(Papyrus(.caption))
Text("Hello World!").modifier(Papyrus(.footnote))
Text("Hello World!").modifier(Papyrus(.subheadline))
Text("Hello World!").modifier(Papyrus(.callout))
Text("Hello World!").modifier(Papyrus())
Text("Hello World!").modifier(Papyrus(.body))
Text("Hello World!").modifier(Papyrus(.headline))
Text("Hello World!").modifier(Papyrus(.title))
Text("Hello World!").modifier(Papyrus(.largeTitle))

您的文本现在无需进一步工作即可动态更改。这是相同的代码,对不同的文本大小偏好使用react:

enter image description here

你的 Papyrus() 实现看起来像这样。您需要为每个类别找出正确的值,这只是一个示例:

struct Papyrus: ViewModifier {
    @Environment(\.sizeCategory) var sizeCategory
    var textStyle: Font.TextStyle

    init(_ textStyle: Font.TextStyle = .body) {
        self.textStyle = textStyle
    }

    func body(content: Content) -> some View {
        content.font(getFont())
    }

    func getFont() -> Font {
        switch(sizeCategory) {
        case .extraSmall:
            return Font.custom("Papyrus", size: 16 * getStyleFactor())
        case .small:
            return Font.custom("Papyrus", size: 21 * getStyleFactor())
        case .medium:
            return Font.custom("Papyrus", size: 24 * getStyleFactor())
        case .large:
            return Font.custom("Papyrus", size: 28 * getStyleFactor())
        case .extraLarge:
            return Font.custom("Papyrus", size: 32 * getStyleFactor())
        case .extraExtraLarge:
            return Font.custom("Papyrus", size: 36 * getStyleFactor())
        case .extraExtraExtraLarge:
            return Font.custom("Papyrus", size: 40 * getStyleFactor())
        case .accessibilityMedium:
            return Font.custom("Papyrus", size: 48 * getStyleFactor())
        case .accessibilityLarge:
            return Font.custom("Papyrus", size: 52 * getStyleFactor())
        case .accessibilityExtraLarge:
            return Font.custom("Papyrus", size: 60 * getStyleFactor())
        case .accessibilityExtraExtraLarge:
            return Font.custom("Papyrus", size: 66 * getStyleFactor())
        case .accessibilityExtraExtraExtraLarge:
            return Font.custom("Papyrus", size: 72 * getStyleFactor())
        @unknown default:
            return Font.custom("Papyrus", size: 36 * getStyleFactor())
        }
    }

    func getStyleFactor() -> CGFloat {
        switch textStyle {
        case .caption:
            return 0.6
        case .footnote:
            return 0.7
        case .subheadline:
            return 0.8
        case .callout:
            return 0.9
        case .body:
            return 1.0
        case .headline:
            return 1.2
        case .title:
            return 1.5
        case .largeTitle:
            return 2.0
        @unknown default:
            return 1.0
        }
    }

}

更新

我修改了实现以接受文本样式作为参数。

关于swift - 是否可以在 SwiftUI 中使用带有自定义字体的动态字体大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56726869/

相关文章:

ios - Swift:遍历 plist

ios - 在 Swift 中拉伸(stretch) UIView

Java GUI 更好地删除或 setVisible(false)?

css - 哪些网站提供公共(public)网络字体库链接?

c# - Xamarin.iOS 上的 Swift 框架 - 已抛出 Foundation.MonoTouchException

ios - UIPopoverController 不调整大小

java - 如何在不控制源代码的情况下 headless 运行 gui Java 应用程序?

c++ - Qt创建移动设备原型(prototype)工具

ios - 找不到添加到 xcode 7 的自定义字体的名称

.Net 不一致的字体渲染