如何为 UIFontMetrics 指定最小 UIContentSizeCategory?

2024-02-16

我有一种基于动态类型创建自动缩放字体的方法,如下所示:

extension UIFont {
    public static func getAutoScalingFont(_ fontName: String, _ textStyle: UIFont.TextStyle) -> UIFont {
        // getFontSize pulls from a map of UIFont.TextStyle and UIFont.Weight to determine the appropriate point size
        let size = getFontSize(forTextStyle: textStyle)
        guard let font = UIFont(name: fontName.rawValue, size: size) else { 
            return UIFont.systemFont(ofSize: size)
        }
        let fontMetrics = UIFontMetrics(forTextStyle: textStyle)
        let traitCollection = UITraitCollection(preferredContentSizeCategory: UIApplication.shared.preferredContentSizeCategory)
        let fontDescriptor = UIFontDescriptor.preferredFontDescriptor(withTextStyle: textStyle, compatibleWith: traitCollection)
        return fontMetrics.scaledFont(for: font, maximumPointSize: fontDescriptor.pointSize)
    }
}

这看起来效果很好;当我更改手机设置中的文本大小滑块值时,字体会根据需要进行缩放。

我现在正在尝试添加逻辑minimumUIContentSizeCategory。也就是说,如果用户将其文本大小值设置为小于我指定的最小大小类别,则字体应按比例缩放,就像他们选择了最小值一样。

这是我的尝试:

extension UIFont {
    // This variable represents the minimum size category I want to support; that is, if the user
    // chooses a size category smaller than .large, fonts should be scaled to the .large size
    private static let minimumSupportedContentSize: UIContentSizeCategory = .large

    public static func getAutoScalingFont(_ fontName: String, _ textStyle: UIFont.TextStyle) -> UIFont {
        let size = getFontSize(forTextStyle: textStyle)
        guard let font = UIFont(name: fontName.rawValue, size: size) else { 
            return UIFont.systemFont(ofSize: size)
        }
        // I've extended UIContentSizeCategory to adhere to Comparable so this works fine
        let contentSize = max(UIApplication.shared.preferredContentSizeCategory, minimumSupportedContentSize)
        let fontMetrics = UIFontMetrics(forTextStyle: textStyle)
        let traitCollection = UITraitCollection(preferredContentSizeCategory: contentSize)
        let fontDescriptor = UIFontDescriptor.preferredFontDescriptor(withTextStyle: textStyle, compatibleWith: traitCollection)
        return fontMetrics.scaledFont(for: font, maximumPointSize: fontDescriptor.pointSize)
    }
}

通过日志我可以看出,正如预期的那样,contentSize我传递给 UITraitCollection 初始值设定项的值永远不会小于.large。但是,传递给该初始值设定项的值似乎代表一个maximum内容大小类别。也就是说,如果我像这样初始化特征集合:

let traitCollection = UITraitCollection(preferredContentSizeCategory: .large)

对于所有小于 UIContentSizeCategory 的字体,字体将重新缩放.large但不会针对大于的任何类别重新缩放.large.

有谁知道如何完成设置minimumUIContentSizeCategory?


虽然我们有minimumContentSizeCategory and maximumContentSizeCategory从 iOS 15 开始支持,但在某些情况下我们仍然需要旧的方式。例如,当我们需要支持动态文本样式时,这两个属性不起作用NSAttributedString.

这是我用旧方法做的,

Use UIApplication.shared.preferredContentSizeCategory来决定哪个preferredContentSizeCategory与使用UITraitCollection

Example:

func getPreferredFont(textStyle: UIFont.TextStyle, weight: UIFont.Weight? = nil) -> UIFont {
    let preferredContentSizeCategory: UIContentSizeCategory
    switch UIApplication.shared.preferredContentSizeCategory {
    case .extraSmall, .small, .medium:
        preferredContentSizeCategory = .large
    case .accessibilityExtraLarge, .accessibilityExtraExtraLarge, .accessibilityExtraExtraExtraLarge:
        preferredContentSizeCategory =  .accessibilityLarge
    default:
        preferredContentSizeCategory = UIApplication.shared.preferredContentSizeCategory
    }
    let traitCollection = UITraitCollection(preferredContentSizeCategory: preferredContentSizeCategory)
    let fontDescriptor = UIFontDescriptor.preferredFontDescriptor(withTextStyle: textStyle, compatibleWith: traitCollection)
    let fontMetrics = UIFontMetrics(forTextStyle: textStyle)
    let font: UIFont
    if let weight = weight {
        font = UIFont.systemFont(ofSize: fontDescriptor.pointSize, weight: weight)
    } else {
        font = UIFont.systemFont(ofSize: fontDescriptor.pointSize)
    }
    return fontMetrics.scaledFont(for: font, maximumPointSize: fontDescriptor.pointSize, compatibleWith: traitCollection)
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何为 UIFontMetrics 指定最小 UIContentSizeCategory? 的相关文章

随机推荐

  • 如何在clickhouse中根据日期和时间段选择数据

    我想通过两者过滤一些数据yyyymmdd 日期 和hhmmss 时间 但是clickhouse不支持time类型 所以我选择datetime将它们结合起来 但如何做这样的事情 这是代码dolphindb 它支持second类型来表示hhmm
  • svnrdump 转储和 svnadmin 转储之间的区别

    我需要 svn 存储库的转储 我找到了两个解决方案 svnrdump dump And svnadmin dump svnrdump dump是相同的svnadmin dump 如果不是 这两个命令有什么区别 svnrdump生成相同的转储
  • UWP ListView DataTemplate 绑定到项目而不是属性

    如何将数据模板中的项目绑定到项目本身 而不是该项目的属性 我有一个将项目作为模型的用户控件 鉴于这些模型 public class Car public string Name get set public Color color get
  • QImage/QPixmap 大小限制?

    是否有任何已知的尺寸 空间限制QPixmap and or QImage记录的对象 我没有找到任何与此相关的有用信息 我目前在 OSX 和 Windows 上使用 Qt 4 7 3 我特别感兴趣的是 宽度 高度限制 限制取决于颜色格式 32
  • UTF-8 和 ISO-8859-1 有什么区别? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 有什么区别UTF 8 https en wikipedia org wiki UTF 8 and ISO 8859 1 https e
  • JSF:commandLink 作为 outputFormat 的参数

    我正在国际化一些 JSF 文件 因此正在外部化字符串 以及使用占位符的字符串连接 我对 JSF 的经验很少 今天和昨天 所以如果我的问题有一个明显的答案 请原谅 我一直在成功地使用 h outputFormat 标记 和 f param 标
  • 用户窗体根据屏幕分辨率调整大小

    我有一个 Excel 用户表单 我想在打开时调整大小以适应屏幕分辨率 我通过得到高度和宽度Application Height and Application Width 通常使用这两个参数和以下代码 应该可以解决问题 Me Top App
  • 以编程方式最大化窗口并防止用户更改窗口状态

    如何以编程方式最大化窗口 以便窗口一旦打开就无法调整大小 达到最大化状态 例如 最大化 Internet Explorer 并查看它 我将 FormWindowState 属性设置为 this WindowState FormWindowS
  • 检测视图中的任何触摸(iPhone SDK)

    我目前正在使用 void touchesBegan NSSet touches withEvent UIEvent event void touchesEnded NSSet touches withEvent UIEvent event
  • 在 Electron 中使用量角器

    我正在尝试为我运行的应用程序设置单元测试和 e2e 测试Electron http electron atom io using 量角器 https angular github io protractor 我参考了很多不同的帖子 this
  • Rails 渲染路线路径

    我对 Rails 还很陌生 很难理解 Rails 中路径系统的工作原理 在我的routes rb中 我创建了一个用于注册的别名 match signup gt user new resource user controller gt use
  • 数据路径 '''' 不应具有附加属性 (es5BrowserSupport)

    尝试在 Angular 中开始 在 CLI 中创建项目后 我尝试使用两者打开项目ng serve o and npm start但我收到以下错误 Schema validation failed with the following err
  • 线程与并行,它们有何不同?

    线程和并行有什么区别 哪一个比另一个有优势 Daniel Moth 我的前同事 线程 并发与并行 http www danielmoth com Blog 2008 11 threadingconcurrency vs parallelis
  • 为什么 Firefox 忽略基于范围查询的缓存控制?

    Web 服务器能够将媒体 本例中为音频 传输到浏览器 浏览器使用 HTML5 控件来播放媒体 然而 我发现 Firefox 正在缓存媒体 尽管我 相信我 明确告诉它不要这样做 我有预感 它与 206 部分内容响应有关 因为带有完整 200
  • 在分页期间获取SQL Server中记录总数的有效方法

    当查询 sql server 中的表时 我试图仅获取当前页的记录 但是 我需要为特定查询返回的记录总数来计算页数 如何在不编写另一个查询来计算记录的情况下有效地执行此操作 WITH allentities AS SELECT Row num
  • 错误 CS0106:修饰符“private”对于此项无效 Unity 中的 C# 错误

    我不断收到此错误 CS0106 修饰符 私有 对此项目无效 并且需要一些帮助 我正在尝试为我的游戏制作一个随机对象生成器 但由于我仍然是新手编码器 我似乎不知道如何解决这个问题 你能帮忙的话 我会很高兴 这是我使用的代码 using Sys
  • 谷歌地图可以根据小时分钟秒绘制点吗

    我正在尝试绘制以时分秒秒格式提供给我的 GPS 数据 GLatLng 会采用这种形式吗 还是我需要先转换它 很难在互联网上找到与此相关的任何内容 如果可以采用这种格式 我们将不胜感激 据我所知它不接受这种格式 但转换它真的很容易 只需计算一
  • Python 中的最佳 ETL 包

    我有两个用例 从 Oracle PostgreSQL Redshift S3 CSV 提取 转换并加载到我自己的 Redshift 集群 安排作业每天 每周运行 INSERT TABLE 或 INSERT NONE 选项更好 我目前正在使用
  • 如何在android中为不同类型的标记指定onMarkerclick()

    在谷歌地图上 我为不同的目的放置不同颜色的标记 在这里我想要每个标记的 onMarkerclick 具有不同的功能 例如 所有绿色标记 如何为此创造条件 这是我创建一组的代码标记数 Override public void onMapLon
  • 如何为 UIFontMetrics 指定最小 UIContentSizeCategory?

    我有一种基于动态类型创建自动缩放字体的方法 如下所示 extension UIFont public static func getAutoScalingFont fontName String textStyle UIFont TextS