在忽略动态类型时修复 SwiftUI iOS 13+ 中自定义字体的大小

Tyl*_*den 7 swift ios13 swiftui dynamic-type-feature ios14

在我正在开发的应用程序(适用于 iOS13 及更高版本的 SwiftUI)中,我导入了自定义字体,并使用以下方法加载该字体”:

func getDigitalXFontOfSize(size s : CGFloat) -> Font {
        return Font.custom("DigitalX", size: s);
}
Run Code Online (Sandbox Code Playgroud)

我在视图中有一个 Text 对象,如下所示:

let font : Font = FontGetter.getDigitalXFontOfSize(20.0);

var body: some View {
        HStack {
            Text("some text").font(FontGetter)
        }
}
Run Code Online (Sandbox Code Playgroud)

在 iOS 中,有一些选项可以在“设置”中更改字体大小,并指出:“支持动态类型的应用程序将在下方调整为您喜欢的阅读大小”。据我所知,SwiftUI 中的 Text 视图会根据 Dynamic Type 值自动采用字体的动态缩放。

现在我明白可访问性非常重要,如果用户想要更大的字体,他们应该能够得到一个等等。我的应用程序是一个网络游戏的附加组件,需要一个非常具体的布局,不遵守非常大或非常小的文本(如 iOS 中可用的文本,例如accessibilityExtraExtraExtraLarge

一些应用程序,如 iOS 版 Reddit 应用程序,似乎完全忽略了设置应用程序中设置的文本大小。

当您在“设置”应用中更改文本大小滑块时,我的应用中的文本大小也会发生变化,这是我不希望发生的。

我可以在我的应用程序中关闭动态类型支持并始终呈现我指定的确切大小的字体吗?如果是这样,怎么做?

我可以为我在应用程序中使用的特定文本视图禁用动态类型吗?

我花了很多时间在 SO 上搜索类似的问题,但似乎找不到适用于 iOS 13 及更高版本或 SwiftUI 的解决方案。以前版本的 iOS(或 swift)没有缩放以相同方式创建的自定义字体,但现在它们似乎可以。

编辑

在 iOS 14 中,有一个创建固定字体大小的选项,如下所示:

func getDigitalXFontOfSize(size s : CGFloat) -> Font {
        return Font.custom("DigitalX", fixedSize: s);
}
Run Code Online (Sandbox Code Playgroud)

这似乎有效。但是对于 iOS 13,我也需要类似的东西。

XLE*_*_22 9

\n

我可以关闭动态类型支持 [\xe2\x80\xa6] 我可以为应用程序中使用的特定文本视图禁用动态类型吗?

\n
\n

禁用该功能的最佳方法Dynamic Type避免使用文本样式
\n但是,就您而言,我强烈建议在不使用其全部功能的情况下考虑此功能(您\xe2\x80\x99有一天可能会需要它,谁知道呢?)

\n

除了 @multitudes 接受的答案之外,展示该Dynamic Type功能本身如何在不被停用的情况下提供这种结果似乎很有趣。

\n

iOS 15引入了新的内容大小类别限制,其目标是使用以下功能设置最小和最大大小Dynamic Type

\n\n

\xe2\x9a\xa0\xef\xb8\x8f 但 \xe2\x80\x99s 建议在WWDC 2021 视频中所述的特定情况下使用它:\xe2\x9a\xa0\xef\xb8\x8f

\n
\n

请不要使用此 API 过度限制文本大小。这些设置具有极其重要的功能,最重要的是,对于使用最高文本大小设置的人来说,您的应用程序\xe2\x80\x99s 功能全部可用,并且一切都清晰可辨。

\n
\n

最后,我建议看一下这篇有趣的文章,它描述了如何Dynamic Type在需要时限制大小(也包括 SwiftUI)。

\n


mul*_*des 6

一个小黑客

看来苹果并没有给我们一个直接的方法来影响动态字体的最大尺寸。

为了避免字体尺寸过小,可以使用minimumScaleFactor修饰符,例如

.minimumScaleFactor(0.5)
Run Code Online (Sandbox Code Playgroud)

要避免太大的字体并不那么容易。

我在应用程序中所做的就是获取名为 sizeCategory 的环境变量,并根据此系统变量的值调整我的字体。

它应该也适合你。在您看来,您应该在结构中添加环境变量。然后,如果您知道这.accessibilityExtraExtraLarge会破坏您的布局,您可以像这样调整它:

struct ContentView: View {
    @Environment(\.sizeCategory) var sizeCategory

    var body: some View {
       Text("Hello World")
         .font(sizeCategory == .accessibilityExtraExtraLarge ?
           .custom("Helvetica", size: 23, relativeTo: .headline) :      
           .custom("Helvetica", size: 33, relativeTo: .headline))
         .minimumScaleFactor(0.5)
    }
}
Run Code Online (Sandbox Code Playgroud)

我没有要测试的完整代码,但我会将其添加到您的函数中,它应该可以工作:

func getDigitalXFontOfSize(size s : CGFloat) -> Font {
    if font(sizeCategory == .accessibilityExtraExtraLarge {
        return Font.custom("DigitalX", size: s - 10)
    } else {
        return Font.custom("DigitalX", size: s)
}
Run Code Online (Sandbox Code Playgroud)

我希望这会有所帮助。我想在函数内部使用 switch 语句也是一个主意!


bjo*_*lau 5

如何在 iOS 15.0+ 上完全禁用字体缩放

我发现您可以通过.dynamicTypeSize(.large)在根视图上进行设置来在应用程序范围内禁用此功能。(.large 似乎是默认值)。

它的行为似乎就像.preferredColorScheme传播到所有子视图一样。

因此,当您在根视图上设置dynamicTypeSize时,您指定固定字体大小的所有字体将不再缩放。