在SwiftUI中可以使用带有自定义字体的动态类型大小吗? [英] Is it possible to use dynamic type sizes with a custom font in SwiftUI?

查看:339
本文介绍了在SwiftUI中可以使用带有自定义字体的动态类型大小吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm playing around with SwiftUI, and want to use a custom UI font for my project. However, I don't want to lose the dynamic type resizing that comes with the built-in font classes (e.g. Large Title).

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

Apple does provide a custom font modifier for Text:

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

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

However, this fixes the size to 17pt. When you run this on a device or in the Simulator and open the Accessibility Inspector to adjust the OS-level font size, the Text element does not update.

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

The size: parameter is not optional, so you must pass in something. And unfortunately, you can't get the size of an existing font (even a custom one), because Font does not have a size parameter.

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

It seems to be a common pattern in the rest of SwiftUI that parameters can either be optional, or you can pass in nil to explicitly disable certain behavior. I would expect the size: parameter on .custom() to be optional, and internally either use the size from a previous Font modifier, or to use the default size set by Text.

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

Alternately, the static methods that define system styles (e.g. .largeTitle) could accept an argument that provides a custom font name: .largeTitle("Papyrus")

有人可以解决吗?

推荐答案

我偶然发现了一种很好的方法,也可以通过ViewModifier来实现这一目标.我从有关动态类型和自定义字体的这篇Hacking with Swift的文章.结果如下:

I stumbled upon a nice way to achieve this also via ViewModifier. I borrowed the base modifier from this Hacking With Swift's article on Dynamic Type and Custom Fonts. Here's the result:

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修饰符,并且可以通过为此问题提供的一种替代方法来进行缩放.

This way you can stick to bundled Text Styles without needing to provide sizes explicitly. Should you want to do so, the font modifier already allow us to, and the scaling could be handled through one of the alternative approaches given to this question.

此外,请注意,由于样式是在ViewModifier兼容的struct中应用的,而样式又会响应对环境sizeCategory的更改,因此视图将在切换回时直接反映对辅助功能设置的更改.您的应用;因此无需重新启动它.

Also, please note that because the styling is applied within a ViewModifier conformant struct, which in turn responds to changes to the environment's sizeCategory, the views will reflect changes to the accessibility settings right upon switching back to your app; so there's no need to restart it.

这篇关于在SwiftUI中可以使用带有自定义字体的动态类型大小吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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