【问题标题】:How do I get a monospace font that respects acessibility settings如何获得尊重可访问性设置的等宽字体
【发布时间】:2018-03-20 10:05:16
【问题描述】:
let bodyFontDescriptor = UIFontDescriptor
    .preferredFontDescriptor(withTextStyle: UIFontTextStyle.body)
let bodyMonospacedFontDescriptor = bodyFontDescriptor.addingAttributes(
    [
        UIFontDescriptorFeatureSettingsAttribute: [
            [
                UIFontFeatureTypeIdentifierKey: kTextSpacingType,
                UIFontFeatureSelectorIdentifierKey: kMonospacedTextSelector
            ]
        ]
    ])
let bodyMonospacedFont = UIFont(descriptor: bodyMonospacedFontDescriptor, size: 0.0)
textview.font = bodyMonospacedFont

这会产生具有可变宽度字符的文本。 我需要在没有硬编码 courier new 的情况下获得等宽字体 和固定大小。 部署目标是 ios 9.0

【问题讨论】:

    标签: ios swift fonts ios9 accessibility


    【解决方案1】:

    这是UIFontDescriptor 的扩展,它返回给定文本样式的首选等宽字体描述符。没有简单的方法可以使用UIFontUIFontDescriptor 获得完全等宽字体。此解决方案试图找到一个好的等宽字体,并在需要时回退到 Courier。

    extension UIFontDescriptor {
        static let monoDescriptor: UIFontDescriptor = {
            // Attempt to find a good monospaced, non-bold, non-italic font
            for family in UIFont.familyNames {
                for name in UIFont.fontNames(forFamilyName: family) {
                    let f = UIFont(name: name, size: 12)!
                    let fd = f.fontDescriptor
                    let st = fd.symbolicTraits
                    if st.contains(.traitMonoSpace) && !st.contains(.traitBold) && !st.contains(.traitItalic) && !st.contains(.traitExpanded) && !st.contains(.traitCondensed) {
                        return fd
                    }
                }
            }
    
            return UIFontDescriptor(name: "Courier", size: 0) // fallback
        }()
    
        class func preferredMonoFontDescriptor(withTextStyle style: UIFontTextStyle) -> UIFontDescriptor {
            // Use the following line if you need a fully monospaced font
            let monoDescriptor = UIFontDescriptor.monoDescriptor
    
            // Use the following two lines if you only need monospaced digits in the font
            //let monoDigitFont = UIFont.monospacedDigitSystemFont(ofSize: 0, weight: .regular)
            //let monoDescriptor = monoDigitFont.fontDescriptor
    
            // Get the non-monospaced preferred font
            let defaultFontDescriptor = preferredFontDescriptor(withTextStyle: style)
            // Remove any attributes that specify a font family or name and remove the usage
            // This will leave other attributes such as size and weight, etc.
            var fontAttrs = defaultFontDescriptor.fontAttributes
            fontAttrs.removeValue(forKey: .family)
            fontAttrs.removeValue(forKey: .name)
            fontAttrs.removeValue(forKey: .init(rawValue: "NSCTFontUIUsageAttribute"))
            let monospacedFontDescriptor = monoDescriptor.addingAttributes(fontAttrs)
    
            return monospacedFontDescriptor.withSymbolicTraits(defaultFontDescriptor.symbolicTraits) ?? monospacedFontDescriptor
        }
    }
    

    请注意 cmets 是否需要完全等宽的字体或仅具有等宽数字的字体。注释/取消注释这些行以满足您的特定需求。

    示例用法:

    let bodyMonospacedFont = UIFont(descriptor: .preferredMonoFontDescriptor(withTextStyle: .body), size: 0)
    textview.font = bodyMonospacedFont
    

    以下是一些测试代码,以确认preferredMonoFontDescriptor(withTextStyle:) 的结果适用于所有样式:

    let textStyles: [UIFontTextStyle] = [ .body, .callout, .caption1, .caption2, .footnote, .headline, .subheadline, .largeTitle, .title1, .title2, .title3 ]
    for style in textStyles {
        let nfont = UIFont(descriptor: .preferredFontDescriptor(withTextStyle: style), size: 0)
        let mfont = UIFont(descriptor: .preferredMonoFontDescriptor(withTextStyle: style), size: 0)
        print(style)
        print(nfont)
        print(mfont)
    }
    

    如果您比较每对结果,它们的大小、重量和样式都相同,只是字体不同。

    【讨论】:

    • 返回的等宽字体之一是“AppleColorEmoji”。您可以通过在条件中添加 && !st.contains(.classSymbolic) 来摆脱它
    • 有没有办法使用特征来查找具有等宽数字的字体列表?在代码中,您将获得带有monospacedDigitSystemFont 的系统等宽数字字体,但我想知道是否还有其他具有等宽数字的字体?
    猜你喜欢
    • 2016-04-02
    • 1970-01-01
    • 1970-01-01
    • 2022-09-23
    • 2021-08-07
    • 2019-12-21
    • 2023-03-27
    • 2010-11-18
    相关资源
    最近更新 更多