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

krugob8w  于 2023-03-16  发布在  Swift
关注(0)|答案(6)|浏览(182)

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

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

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

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

var body: some View {
        HStack {
            Text("some text").font(FontGetter)
        }
}

在iOS中,设置中有更改字体大小的选项,它指出:“支持动态类型的应用程序将在下面调整到您首选的阅读大小”。而且据我所知,SwiftUI中的文本视图会根据动态类型值自动采用字体的动态缩放。
现在,我明白了可访问性是非常重要的,如果用户想要一个更大的字体,他们应该能够得到一个等。我的应用程序是一个网络游戏的插件,需要一个非常具体的布局,不坚持非常大或非常小的文本(如在iOS中可用的accessibilityExtraExtraExtraLarge
一些应用程序,如iOS版的Reddit应用程序,似乎完全忽略了设置应用程序中设置的文本大小。
当你在设置应用程序中改变文本大小滑块时,文本大小在我的应用程序中也会改变,这是我不希望发生的。
我是否可以关闭应用中的动态类型支持,并始终按照我指定的字体大小呈现字体?如果可以,该如何操作?
我可以禁用应用程序中使用的特定文本视图的动态类型吗?
我花了很多时间搜索类似的问题,但我似乎找不到一个解决方案的iOS 13和以上或SwiftUI.以前版本的iOS(或swift)没有规模定制字体创建相同的方式,但现在他们似乎。

编辑

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

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

这看起来很有效。但我也需要iOS 13也有这样的东西。

6kkfgxo0

6kkfgxo01#

∮一个小黑客∮
苹果似乎没有给予我们一个直接的方法来影响动态字体的最大大小。
为了避免字体太小,可以使用minimumScaleFactor修饰符,如

.minimumScaleFactor(0.5)

要避免非常大的字体并不那么容易。
我在我的应用程序中所做的是获取名为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)
    }
}

我没有你的完整代码测试,但我会添加到您的函数,它应该工作:

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

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

368yc8dk

368yc8dk2#

我可以关闭动态类型支持吗[...]我可以为我在应用程序中使用的特定文本视图禁用动态类型吗?
禁用Dynamic Type功能的最佳方法是避免使用文本样式
然而,在您的情况下,我强烈建议考虑这个功能,但不要使用它的全部功能 (你可能有一天会需要它,谁知道呢?)。🤔
除了@ multudes接受的答案👏之外,展示Dynamic Type特性本身如何在不被停用的情况下提供这种结果似乎很有趣。

iOS 15引入了new content size category limits,其目标是通过Dynamic Type功能设置最小和最大大小:🤓

但️建议在WWDC 2021 video中所述的特定情况下使用它:⚠️
请不要使用此API来过度限制文本大小。这些设置具有极其重要的功能,对于使用最大文本大小设置的用户来说,您的应用的所有功能都可用并且所有内容都清晰可辨是至关重要的。
最后,我建议看一下this interesting article,它描述了如何在需要时限制Dynamic Type的大小。👍

6pp0gazn

6pp0gazn3#

如果有人正在寻找一个固定大小的系统字体(像我一样):

.font(.system(size: 8))

(在iOS 14下工作,13下我不知道)

aor9mmx1

aor9mmx14#

以下是对我有效的方法,

Text("Hello")
            .font((sizeCategory == .extraExtraExtraLarge || sizeCategory == .extraExtraLarge) ?
                       .custom("Helvetica", size: 110) :
                       .custom("Helvetica", size: 130))
            .minimumScaleFactor(0.5)
            .foregroundColor(.white)
q1qsirdb

q1qsirdb5#

iOS 15.0以上版本

我发现你可以通过在根视图上设置.dynamicTypeSize(.large)(.large似乎是默认值)来在应用程序范围内禁用这个功能。
它的行为看起来像.preferredColorScheme,它向下传播到所有子视图。
因此,当您在根视图上设置了dynamicTypeSize时,您指定了固定字体大小的所有字体将不再缩放。

lxkprmvk

lxkprmvk6#

最后,我找到了一个将UIFont转换为字体的解决方案。我已经测试过了,它可以在我的设备上工作。
您可以在iOS13及以上版本上使用此代码。

extension Font {
    static let fontName = "Quicksand-Light_Bold"
    static func quickSand(size: CGFloat) -> Font {
        if let uifont =  UIFont(name: fontName, size: size) {
            return Font(uifont as CTFont)
        }
        return Font.custom(fontName, size: size)
    }
}

UIFont to Font

相关问题