如何应对 macOS 14 Sonoma 中新的文本大小设置?

问题描述 投票:0回答:1

总结

macOS 14 Sonoma 在“设置”->“辅助功能”->“显示”下添加了“文本大小”设置。这类似于 iOS 中已经存在相当长一段时间的“文本大小”设置。

许多 Apple 应用程序会根据此设置自动调整文本大小。这包括 Xcode、设置、Finder、邮件、便笺等。 Xcode 和“设置”等应用程序仅更改侧边栏中的文本,而其他应用程序则更改整个应用程序中的文本。

问题

我的问题是如何在我自己的 macOS 应用程序中响应此设置?

研究

我搜索了 AppKit 文档。我搜索过 WWDC 视频。我搜索过苹果开发者论坛。我见过没有提到这是如何完成的。

在这里我看到了:

实验

我使用 AppKit 创建了一个本机 macOS 应用程序。我添加了一个

NSTextField
和一个
NSTextView
并将字体设置为文本样式,例如“Title 1”。更改设置不会自动更改应用程序中显示的字体大小。

我创建了一个 SwiftUI 应用程序并添加了本机 macOS 版本。我使用

ContentView
设置了一个
Text
和一些
Text("This is some text").font(.title)
。更改设置不会自动更改应用程序中显示的字体大小。

我有一个使用 Mac Catalyst 为 macOS 构建的 iOS 应用程序。当 iOS 设置应用程序中的“文本大小”设置更改时,iOS 版本的应用程序会自动调整其文本。在 macOS 设置应用程序中更改“文本大小”设置时,应用程序的 macOS 版本根本不会改变。

在本机 AppKit 应用程序中,我在

AppDelegate
中尝试了以下代码:

NSWorkspace.shared.notificationCenter.addObserver(forName: nil, object: nil, queue: nil) { note in
    print(note)
}
NotificationCenter.default.addObserver(forName: nil, object: nil, queue: nil) { note in
    print(note)
}

更改“文本大小”设置时,这些都不会生成任何输出。在 iOS/UIKit 下,您会收到

UIContentSizeCategory.didChangeNotification
通知。

作为一个盲目的尝试,我使用自己的自定义

NSApplication
子类设置了 AppKit 应用程序,并添加了以下内容:

class Application: NSApplication {
    override func sendEvent(_ event: NSEvent) {
        print("event \(event)")
        super.sendEvent(event)
    }

    override func sendAction(_ action: Selector, to target: Any?, from sender: Any?) -> Bool {
        print("action: \(action)")
        return super.sendAction(action, to: target, from: sender)
    }
}

更改“文本大小”设置时,这些都不会产生输出。

总结

我现在很茫然。需要哪些代码才能允许 macOS 应用程序响应“文本大小”设置的更改?我迫切需要的是使用 Mac Catalyst 为 macOS 构建的 iOS/UIKit 应用程序,但我对本机 AppKit 甚至 SwiftUI 中的解决方案很满意。代码可以是 Swift 或 Objective-C。

macos swiftui uikit appkit mac-catalyst
1个回答
0
投票

使用
defaults

获取文本大小

文本大小存储在

com.apple.universalaccess.plist
FontSizeCategory
:

$ defaults read com.apple.universalaccess FontSizeCategory

# {
#     "com.apple.MobileSMS" = UseGlobal;
#     "com.apple.Notes" = UseGlobal;
#     "com.apple.finder" = UseGlobal;
#     "com.apple.iBooksX" = UseGlobal;
#     "com.apple.iCal" = UseGlobal;
#     "com.apple.mail" = UseGlobal;
#     "com.apple.news" = UseGlobal;
#     "com.apple.stocks" = UseGlobal;
#     "com.apple.weather" = UseGlobal;
#     global = DEFAULT;
#     version = "3.0";
# }

global
是我们感兴趣的。

以下是“设置”应用程序中可能的值和相应选项的列表:

价值 文字大小 侧边栏图标大小
XXXS
9分
XXS
10分
XS
11分
S
12分
DEFAULT
默认(11点)
M
13分
L
14点
XL
15分
XXL
16分
XXXL
17分
AX1
20分
AX2
24点
AX3
29分
AX4
35点
AX5
42点

观察代码中文本大小的变化

观察文字大小变化:

  1. 创建一个

    UserDefaults
    对象,套件名称为
    com.apple.universalaccess
    。确保您对其保持强引用,否则您不会收到 KVO 回调。

  2. 使用 KVO 观察键

    FontSizeCategory
    的变化。

extension UserDefaults {
    // I'm using `observe(_:options:changeHandler:)` below and it only accept 
    // a `KeyPath` key path, so this is required for this use case. 
    // Notice the the property name is the same as the key `FontSizeCategory`, 
    // because the property name is used as the KVO key.
    @objc var FontSizeCategory: [String: Any]? {
        dictionary(forKey: "FontSizeCategory")
    }
}

let universalAccessDefaults = UserDefaults(suiteName: "com.apple.universalaccess")!
var fontSizeCategoryObservation: NSKeyValueObservation?

fontSizeCategoryObservation = universalAccessDefaults.observe(\.FontSizeCategory, options: .new) { [unowned self] _, changes in
    guard let newValue = changes.newValue.flatMap(\.self), let global = newValue["global"] as? String else { return }
    print(global)
    /* Update your UI for text size change */
}

有人说这需要临时例外权利,并且 App Store 通常不允许

获取文本大小的缩放字体大小

不幸的是,我们在 macOS API 中还没有动态类型。像

NSFont.preferredFont(forTextStyle:)
这样的方法总是返回固定的字体大小。

目前,我们需要维护一个从 iOS 迁移的我们自己的字体大小列表。这是很多工作,而且我对排版几乎一无所知,所以我把这个留给你了。

以下是一些可能有用的链接:

© www.soinside.com 2019 - 2024. All rights reserved.