简体   繁体   English

具有自定义大小的文本样式的系统字体

[英]System Font with custom size for text style

Aim:目标:

I would like to know how to use a system font in my SwiftUI app with a custom size that supports dynamic size (that changes when the user changes the text size on the device, font size changes dynamically).我想知道如何在我的SwiftUI应用程序中使用支持动态大小的自定义大小的系统字体(当用户更改设备上的文本大小时,字体大小会动态变化)。

Problem:问题:

I can use the standard .body , .title etc for system fonts, however I want to use a custom size which is slightly different however still want to make sure it works with dynamic types我可以为系统 fonts 使用标准的.body.title等,但是我想使用稍微不同的自定义大小,但仍然想确保它适用于动态类型

My Failed Attempt:我的失败尝试:

//Font size doesn't change when the user changes his preferred text size on the device
Text("hello")
    .font(.system(size: 14, weight: .bold, design: .default))

Note:笔记:

I am targeting iOS 15 , I am looking for something on the lines of the following for system font:我的目标是iOS 15 ,我正在寻找以下系统字体的内容:

static func custom(_ name: String, size: CGFloat, relativeTo textStyle: Font.TextStyle) -> Font

Questions:问题:

  • Is there a way to specify the system font name in the above API?有没有办法在上面的API中指定系统字体名称? If so what is the font name for iOS 15 and macOS Monterey?如果是这样,iOS 15 和 macOS Monterey 的字体名称是什么?
  • Is there any other way to achieve dynamic fonts for system font with custom sizes?对于具有自定义大小的系统字体,还有其他方法可以实现动态 fonts 吗?

There isn't a way to do this, however I realised that one of the pre-defined text styles meets the requirements.没有办法做到这一点,但是我意识到预定义文本 styles 之一符合要求。

There is a way to chain together font modifiers (styling a font like bold() )有一种方法可以将字体修饰符链接在一起(设置像bold()这样的字体)

Example:例子:

.font(.body.bold())

I made it with somewhat hacky font size estimation based on current sizeCategory :我根据当前sizeCategory进行了一些 hacky 字体大小估计:


public enum AppTextStyle {
    case veryCustomTextStyle
    case anotherCustomTextStyle
}

struct ScaledFontModifier: ViewModifier {
    
    @Environment(\.sizeCategory) var sizeCategory
    var textStyle: AppTextStyle

    func body(content: Content) -> some View {
        content.font(font(for: textStyle))
    }
    
    private func font(for style: AppTextStyle) -> Font {
        switch style {
        case .veryCustomTextStyle:
            return .system(size: scaledValue(for: 42))
        case .anotherCustomTextStyle:
            return .system(size: scaledValue(for: 42), weight: .medium)
        }
    }

    private func scaledValue(for size: CGFloat) -> CGFloat {
        switch sizeCategory {
        case .extraSmall:
            return size - 3
        case .small:
            return size - 2
        case .medium:
            return size - 1
        case .large:
            return size
        case .extraLarge:
            return size + 2
        case .extraExtraLarge:
            return size + 4
        case .extraExtraExtraLarge:
            return size + 6
        case .accessibilityMedium:
            return size + 11
        case .accessibilityLarge:
            return size + 16
        case .accessibilityExtraLarge:
            return size + 23
        case .accessibilityExtraExtraLarge:
            return size + 30
        case .accessibilityExtraExtraExtraLarge:
            return size + 36
        @unknown default:
            return size
        }
    }
}

public extension View {
    func font(_ textStyle: AppTextStyle) -> some View {
        modifier(ScaledFontModifier(textStyle: textStyle))
    }
}

You can use it along the built-in fonts, or you can put all your app text styles in AppTextStyle enum:你可以沿着内置的 fonts 使用它,或者你可以把你所有的应用文本 styles 放在AppTextStyle枚举中:

Text("Hello")
    .font(.body)
Text("World")
    .font(.veryCustomTextStyle)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM